Mongoose: how to use aggregate and find together Mongoose: how to use aggregate and find together mongoose mongoose

Mongoose: how to use aggregate and find together


For MongoDB 3.6 and greater, use the $expr operator which allows the use of aggregation expressions within the query language:

var followers_count = 30;db.locations.find({   "$expr": {        "$and": [           { "$eq": ["$name", "development"] },           { "$gte": [{ "$size": "$followers" }, followers_count ]}       ]    }});

For non-compatible versions, you can use both the $match and $redact pipelines to query your collection. For example, if you want to query the locations collection where the name is 'development' and followers_count is greater than 30, run the following aggregate operation:

const followers_count = 30;Locations.aggregate([    { "$match": { "name": "development" } },    {        "$redact": {            "$cond": [                { "$gte": [ { "$size": "$followers" }, followers_count ] },                "$$KEEP",                "$$PRUNE"            ]        }    }]).exec((err, locations) => {    if (err) throw err;    console.log(locations);})

or within a single pipeline as

Locations.aggregate([    {        "$redact": {            "$cond": [                {                     "$and": [                        { "$eq": ["$name", "development"] },                        { "$gte": [ { "$size": "$followers" }, followers_count ] }                     ]                },                "$$KEEP",                "$$PRUNE"            ]        }    }]).exec((err, locations) => {    if (err) throw err;    console.log(locations);})

The above will return the locations with just the _id references from the users. To return the users documents as means to "populate" the followers array, you can then append the $lookup pipeline.


If the underlying Mongo server version is 3.4 and newer, you can run the pipeline as

let followers_count = 30;Locations.aggregate([    { "$match": { "name": "development" } },    {        "$redact": {            "$cond": [                { "$gte": [ { "$size": "$followers" }, followers_count ] },                "$$KEEP",                "$$PRUNE"            ]        }    },    {        "$lookup": {            "from": "users",            "localField": "followers",            "foreignField": "_id",            "as": "followers"        }    }]).exec((err, locations) => {    if (err) throw err;    console.log(locations);})

else you would need to $unwind the followers array before applying $lookup and then regroup with $group pipeline after that:

let followers_count = 30;Locations.aggregate([    { "$match": { "name": "development" } },    {        "$redact": {            "$cond": [                { "$gte": [ { "$size": "$followers" }, followers_count ] },                "$$KEEP",                "$$PRUNE"            ]        }    },    { "$unwind": "$followers" },    {        "$lookup": {            "from": "users",            "localField": "followers",            "foreignField": "_id",            "as": "follower"        }    },    { "$unwind": "$follower" },    {        "$group": {            "_id": "$_id",            "created": { "$first": "$created" },            "name": { "$first": "$name" },            "followers": { "$push": "$follower" }        }    }]).exec((err, locations) => {    if (err) throw err;    console.log(locations);})


You can use as the following:

db.locations.aggregate([  {$match:{"your find query"}},  {$project:{"your desired fields"}}])

In the match you can do stuff like:

{{$match:{name:"whatever"}}

In the project, you can select the fields you want using numbers 0 or 1 like:

{$project:{_id:1,created:0,name:1}}

Which 0 means, do not put and 1 means put.