Danny Buonocore
Danny Buonocore

Reputation: 3777

Count documents and return subset

Is there a way to use to MongoDB aggregate framework to:

  1. Count the number of documents returned from a $match
  2. Obtain a subset of these documents with another $match

all in one query? I was thinking there might be a way to use multiple $group stages in the pipeline to count the documents before the additional $match then pass the result to the second $group. But I haven't found a way to manage that.

Upvotes: 1

Views: 79

Answers (1)

mickl
mickl

Reputation: 49945

Yes, that's possible and you need $facet pipeline stage which allows you to perform multiple sub-aggregations. Given data like this:

db.col.save({ a: 1, b: 2 })
db.col.save({ a: 1, b: 2 })
db.col.save({ a: 1, b: 2 })
db.col.save({ a: 1, b: 4 })
db.col.save({ a: 3, b: 2 })

You can use below aggregation:

db.col.aggregate([
    {
        $match: { a: 1 }
    },
    {
        $facet: {
            total : [
                { $count: "count" }
            ],
            subset: [
                { $match: { b: 2 } },
                { $project: { _id: 0 } }
            ]
        }
    }
])

which outputs:

{ "total" : [ { "count" : 4 } ], "subset" : [ { "a" : 1, "b" : 2 }, { "a" : 1, "b" : 2 }, { "a" : 1, "b" : 2 } ] }

Each sub-aggregation will be returned as an array however you can apply next pipeline stages like for instance $unwind on count.

Upvotes: 1

Related Questions