Mongo圈子查询

时间:2014-01-10 09:18:23

标签: mongodb

我可以运行查询以获取确切的文档数量吗?

我有收藏:


    > db.circle.find()
    { "_id" : 1 }
    { "_id" : 2 }
    { "_id" : 3 }

执行查询:


    > db.circle.find().skip(2).limit(2)
    { "_id" : 3 }

作为回应1文件,但我需要2

查看此回复的最佳方式是什么?


    { "_id" : 3 }
    { "_id" : 1 }

3 个答案:

答案 0 :(得分:2)

我找到了一种使用聚合框架在一个查询中解决此问题的方法:

result = db.circle.aggregate([
    {   
        $project: {
            virtual_id: { $ifNull: [null, [1, 2]] }
            // extra fields go here...
        }
    },
    { $unwind: '$virtual_id' },
    { $sort: { virtual_id: 1, _id: 1 } },

    { $skip: 2 },
    { $limit: 2 }   
]);

这基本上是复制数据集,将其追加到最后然后应用跳过&限制操作。

步骤:

  1. $project添加virtual_id字段,将数组[1, 2]作为值添加到每个文档中。使用静态值添加字段的$ifNull方法是我在this answer中找到的一个很好的黑客。

  2. $unwind virtual_id将数据集加倍。

  3. $sort确保正确排序两个连接的数据集。完成此操作后,_id值将为:1, 2, 3, 1, 2, 3

  4. $skip$limit执行明显的

  5. 注1

    如果除了_id之外还需要检索任何其他字段,则应在$project操作中指定它们(默认情况下会检索_id)。例如,要在输出中获取extra_fieldyet_another_field的值,请执行:

            $project: {
                virtual_id: { $ifNull: [null, [1, 2]] },
                extra_field: 1,
                yet_another_field: 1
            }
    

    注2

    此解决方案可能不适用于非常大的数据集,因为:

    • 聚合框架的输出大小有限(我相信是16MB)
    • $sort操作可能很昂贵,因为无法定义任何索引以涵盖virtual_id

答案 1 :(得分:0)

The cursor.skip() method is often expensive because it requires the server to walk from 
the beginning of the collection or index to get the offset or skip position before 
beginning to return result

在您的代码db.circle.find().skip(2).limit(2)中,它将跳过前2个文档,然后返回2。 有关详细信息,请参阅cursor.skip()

如果要跳过具有特定ID的文档,请使用$ne运算符:

 db.circle.find({"_id":{ "$ne" : 2}})

它将返回以下文件:

{ "_id" : 3 }
{ "_id" : 1 }

答案 2 :(得分:0)

我使用了db.collection.count()

  

Docs

     

db.collection.count()

     

返回与find()查询匹配的文档数。该   db.collection.count()方法不执行find()操作   而是计算并返回与查询匹配的结果数。