在以下查询中:
db.orders.aggregate([{ $match : { status: "A"}, { $limit: 5} }]);
如何在应用限制之前获取收藏计数?我仍然希望调用返回5个文档的数组。如果我使用$ group,它似乎不会保留文档数组。这可以在一个电话中完成,还是我必须拨打两个电话?
答案 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 } ]
// }
此:
首先match
个status
为A
的文档。
,然后通过$facet
阶段从两个不同的聚合管道中产生两个字段:
$count
仅提供了前$match
阶段产生的文档数。
sample
是$limit
前一个阶段$match
的文档摘录。
答案 1 :(得分:3)
不幸的是,现在你必须进行两次调用,一次使用$ limit运算符调用结果,然后再调用第二次调用。您可以使用聚合框架而不使用$ limit运算符和$ group运算符来计算计数,或者wdberkeley指出您可以将条件传递给.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]
如果您对大型数据集进行了复杂的聚合调用,则这比进行两次调用要快得多。