【问题标题】:Limiting Query result in MongoDB限制 MongoDB 中的查询结果
【发布时间】:2016-04-01 15:09:07
【问题描述】:

我的 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() 函数产生的总文档数)

有什么建议吗?谢谢

【问题讨论】:

    标签: mongodb mongodb-query aggregation-framework


    【解决方案1】:

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

    【讨论】:

    • 啊,谢谢你这么快的回答。那么我如何得到总的结果呢?我的意思是,我想知道有多少文档计数表单 find() 而不查询相同的搜索参数两次?
    • 我不确定你的意思。您想通过将结果集限制为 3 来计算获得了多少结果?
    • 不,我构建了一个数据表(jquery 数据表),它需要类似 - var total = db.transaction.find().length;和 var data = db.transaction.find().skip(2).limit(3)。 TOTAL 和 DATA 是不同的东西
    • 好吧,那么您应该首先在问题中说明这一点。我想我回答的正是你所问的。用聚合管道的描述回答有关如何在 mongo 中跳过和限制查找查询的问题将是一个矫枉过正的问题。
    • 可能。虽然如果这是纯粹的 mongo 问题,它怎么能与任何与猫鼬有关的东西重复呢?我同意这太容易了。如果不先提出额外的问题,就不应该回答这些问题吗? - 我不确定,因为我还没有写答案的丰富经验。
    【解决方案2】:

    我想你的收藏中有以下文档。

    { "_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 在comment 中指出的那样

    $group 将读取所有文档并使用它们构建一个 20k 元素数组,以获得三个文档。

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

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

    db.collection.count()
    

    【讨论】:

    • 好主意,但 $group 将读取所有文档并用它们构建一个 20k 元素数组,只是为了获得三个文档。很难相信这会比两个查询更有效。
    猜你喜欢
    • 2011-01-18
    • 1970-01-01
    • 1970-01-01
    • 2011-09-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-17
    • 1970-01-01
    相关资源
    最近更新 更多