在MongoDB中限制查询结果

7

我在我的mongodb中有20,000多个文档,但我刚学到不能一次性查询所有文档。

所以我的问题是:

我想使用find(query)获取我的文档,然后仅限制结果为3个文档,并且我可以选择从哪些文档开始。

例如,如果我的find()查询返回了8个文档:

[{doc1}, {doc2}, {doc3}, {doc4}, {doc5}, {doc6}, {doc7}, {doc 8}]

命令limit(2, 3)将会返回[doc3, doc4, doc5]

我还需要获取所有结果的总数(不包括限制),例如:length()将会返回8(这是由find()函数返回的文档总数)

有什么建议吗?谢谢

2个回答

10

在您的查询末尾添加.skip(2).limit(3)


啊,谢谢您的快速回答。那么我该如何获得总结果呢?我的意思是,我想知道find()返回的文档数量,而不必查询相同的搜索参数两次。 - DennyHiu
我不确定你的意思。你想通过将结果集限制为3来计算得到多少结果吗? - Martins Untals
5
那么,你应该在问题中首先说明这一点。我认为我回答了你所问的内容。关于如何在Mongo中跳过和限制查找查询的问题作出聚合管道描述的回答会有些过头了。 - Martins Untals
1
可能吧。但如果这是一个纯粹的Mongo问题,它怎么可能与任何与Mongoose相关的内容重复呢?虽然我同意这个问题太简单了。在回答之前应该先询问额外的问题,这样才能得到更好的答案。我不确定,因为我还没有写答案的丰富经验。 - Martins Untals
@MartinsUntals:我的错,非常抱歉我之前忘记添加有关总数的详细信息。不过还是谢谢你的回答。 - DennyHiu
显示剩余4条评论

5
我想你的收藏中应该有以下文件。
{ "_id" : ObjectId("56801243fb940e32f3221bc2"), "a" : 0 }
{ "_id" : ObjectId("56801243fb940e32f3221bc3"), "a" : 1 }
{ "_id" : ObjectId("56801243fb940e32f3221bc4"), "a" : 2 }
{ "_id" : ObjectId("56801243fb940e32f3221bc5"), "a" : 3 }
{ "_id" : ObjectId("56801243fb940e32f3221bc6"), "a" : 4 }
{ "_id" : ObjectId("56801243fb940e32f3221bc7"), "a" : 5 }
{ "_id" : ObjectId("56801243fb940e32f3221bc8"), "a" : 6 }
{ "_id" : ObjectId("56801243fb940e32f3221bc9"), "a" : 7 }

从 MongoDB 3.2 开始,您可以使用 .aggregate() 方法和 $slice 运算符。
db.collection.aggregate([
    { "$group": {
        "_id": null, 
        "count": { "$sum": 1 }, 
        "docs": { "$push": "$$ROOT" }
    }}, 
    { "$project": { 
        "count": 1, 
        "_id": 0,
        "docs": { "$slice": [ "$docs", 2, 3 ] }
    }}
])

返回:

{
        "count" : 8,
        "docs" : [
                {
                        "_id" : ObjectId("56801243fb940e32f3221bc4"),
                        "a" : 2
                },
                {
                        "_id" : ObjectId("56801243fb940e32f3221bc5"),
                        "a" : 3
                },
                {
                        "_id" : ObjectId("56801243fb940e32f3221bc6"),
                        "a" : 4
                }
        ]
}

在分组之前,您可能希望使用 $sort 运算符对文档进行排序。



从MongoDB 3.0开始,您需要首先对文档进行$group操作,并使用$sum累加器运算符返回文档的“计数”;在同一组阶段中,您还需要使用$push$$ROOT变量返回所有文档的数组。然后,管道中的下一个阶段将是$unwind阶段,您可以在其中对该数组进行去规范化处理。从那里使用$skip$limit运算符分别跳过前2个文档,并将3个文档传递到下一个阶段,即另一个$group阶段。
db.collection.aggregate([
    { "$group": {
        "_id": null, 
        "count": { "$sum": 1 }, 
        "docs": { "$push": "$$ROOT" }
    }}, 
    { "$unwind": "$docs" }, 
    { "$skip": 2 }, 
    { "$limit": 3 }, 
    { "$group": {
        "_id": "$_id", 
        "count": { "$first": "$count" }, 
        "docs": { "$push": "$docs" }
    }}
])

正如@JohnnyHK在评论中指出的那样

$group将读取所有文档并构建一个包含20k元素的数组,只为获取三个文档。

然后您应该使用find()运行两个查询

db.collection.find().skip(2).limit(3)

并且

db.collection.count()

3
好的想法,但 $group 会读取所有文档并构建一个包含 20k 元素的数组,只是为了获取三个文档。很难相信这比两个查询更有效率。 - JohnnyHK

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接