In the following query:
db.orders.aggregate([{ $match : { status: "A"}, { $limit: 5} }]);
How can I get the count of documents after the $match
but before the $limit
is applied?
I still want to return an array of 5 documents. But if I use $group
it seems that it would not preserve the array of documents. Can this be done in one call, or do I have to make two calls?
MongoDB $count AggregationThe MongoDB $count operator allows us to pass a document to the next phase of the aggregation pipeline that contains a count of the documents. There a couple of important things to note about this syntax: First, we invoke the $count operator and then specify the string.
Returns as a BIGINT the number of rows in each group where the expression is not NULL . If the query has no GROUP BY clause, COUNT returns the number of table rows. The COUNT aggregate function differs from the COUNT analytic function, which returns the number over a group of rows within a window.
Answer: $skip before $limit In aggregate, $limit limits the number of documents sent to the next aggregation state, and $skip skips the first N documents, so if $skip is after $limit and $skip >= $limit, you won't get any results.
Starting in Mongo 3.4
, the $facet
aggregation stage allows processing multiple aggregation pipelines within a single stage on the same set of input documents:
// { "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 } ]
// }
This:
starts by match
ing documents whose status
is A
.
and then produces via a $facet
stage two fields that out of two distinct aggregation pipelines:
$count
that simply provides the number of documents resulting from the preceding $match
stage.
sample
that is a $limit
ed extract of documents resulting from the preceding $match
stage.
Unfortunately, right now you have to make two calls, one call with the $limit operator for your results followed by a second call for the count. You could use the aggregation framework without the $limit operator and with a $group operator to calculate a count or as wdberkeley points out you can pass your criteria to .count() to get a count instead of using the aggregation framework if you are using a single match stage.
See MongoDB - Aggregation Framework (Total Count).
This can now be done in one call as of version 3.4 with the $facet
aggregation. See here for an example: Mongo aggregation with paginated data and totals
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With