如何在Mongo聚合管道中的限制之前获取计数

时间:2014-09-18 16:34:57

标签: mongodb count limit aggregation-framework

在以下查询中:

db.orders.aggregate([{ $match : { status: "A"}, { $limit: 5} }]);

如何在应用限制之前获取收藏计数?我仍然希望调用返回5个文档的数组。如果我使用$ group,它似乎不会保留文档数组。这可以在一个电话中完成,还是我必须拨打两个电话?

4 个答案:

答案 0 :(得分:12)

Mongo 3.4开始,$facet聚合阶段允许在同一输入文件集的单个阶段中处理多个聚合管道:

// { "status" : "A", "v" : 3 }
// { "status" : "B", "v" : 14 }
// { "status" : "A", "v" : 7 }
// { "status" : "A", "v" : 5 }
db.collection.aggregate(
  { $match: { status: "A"} },
  { $facet: {
      count:  [{ $count: "count" }],
      sample: [{ $limit: 2 }]
  }}
)
// {
//   "count" : [ { "count" : 3 } ],
//   "sample" : [ { "status" : "A", "v" : 3 }, { "status" : "A", "v" : 7 } ]
// }

此:

  • 首先matchstatusA的文档。

  • ,然后通过$facet阶段从两个不同的聚合管道中产生两个字段:

    • $count仅提供了前$match阶段产生的文档数。

    • sample$limit前一个阶段$match的文档摘录。

答案 1 :(得分:3)

不幸的是,现在你必须进行两次调用,一次使用$ limit运算符调用结果,然后再调用第二次调用。您可以使用聚合框架而不使用$ limit运算符和$ group运算符来计算计数,或者wdberkeley指出您可以将条件传递给.count()以获取计数而不是使用聚合框架(如果您使用的话)一个匹配阶段。

请参阅MongoDB - Aggregation Framework (Total Count)

答案 2 :(得分:0)

现在可以使用$facet聚合从3.4版本开始的一个调用中完成此操作。参见此处的示例:Mongo aggregation with paginated data and totals

答案 3 :(得分:-2)

另一种选择是限制应用程序层而不是Mongo查询中的结果。然后你可以得到完整结果的计数,你不必打两个电话。

例如,在Python中你可以这样做:

data = db.orders.aggregate([{ "$match" : { "status": "A"} }])['result']
count = len(data)
data = data[skip:skip+limit]

如果您对大型数据集进行了复杂的聚合调用,则这比进行两次调用要快得多。