Mongoose: how to use aggregate and find together

How can I use aggregate and find together in Mongoose?
those. I have the following diagram:

 const schema = new Mongoose.Schema({ created: { type: Date, default: Date.now() }, name: { type: String, default: 'development' } followers: [{ type: Mongoose.Schema.ObjectId, ref: 'Users'}] ... }) export default Mongoose.model('Locations', schema) 

How can I request users with only the name and followers_count fields.
followers_count : length of followers .

There, I know, we can use select to get only the name field.
How can we get followers counter?

+8
mongodb mongoose mongodb-query aggregation-framework
source share
2 answers

For MongoDB 3.6 and above, use the $expr operator, which allows you to use aggregation expressions inside the query language:

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

For incompatible versions, you can use both $match and $redact to request your collection. For example, if you want to query the locations collection, where the name "development" and followers_count 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 inside one conveyor 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 locations using only _id links from users. To return user documents as a means of β€œpopulating” an array of followers, you can add a $lookup pipeline.


If the base version of the Mongo server is 3.4 or 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 will need a $unwind array of followers before applying $lookup , and then regroup using $group 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); }) 
+9
source share

You can use the following:

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

In a match you can do things like:

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

In the project, you can select the required fields using the numbers 0 or 1, for example:

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

What value 0 means do not put and 1 means put.

+4
source share

All Articles