$ Moongoose match amount does not match id

I want to show products using identifiers ( 56e641d4864e5b780bb992c6 and 56e65504a323ee0812e511f2 ) and show the price after subtraction with a discount, if available.

I can calculate the final price using an aggregate, but this returns the whole document in the collection, how to make it return only matches ids

 "_id" : ObjectId("56e641d4864e5b780bb992c6"), "title" : "Keyboard", "discount" : NumberInt(10), "price" : NumberInt(1000) "_id" : ObjectId("56e65504a323ee0812e511f2"), "title" : "Mouse", "discount" : NumberInt(0), "price" : NumberInt(1000) "_id" : ObjectId("56d90714a48d2eb40cc601a5"), "title" : "Speaker", "discount" : NumberInt(10), "price" : NumberInt(1000) 

this is my request

 productModel.aggregate([ { $project: { title : 1, price: { $cond: { if: {$gt: ["$discount", 0]}, then: {$subtract: ["$price", {$divide: [{$multiply: ["$price", "$discount"]}, 100]}]}, else: "$price" } } } } ], function(err, docs){ if (err){ console.log(err) }else{ console.log(docs) } }) 

and if I add this request to $in , it returns an empty array

 productModel.aggregate([ { $match: {_id: {$in: ids}} }, { $project: { title : 1, price: { $cond: { if: {$gt: ["$discount", 0]}, then: {$subtract: ["$price", {$divide: [{$multiply: ["$price", "$discount"]}, 100]}]}, else: "$price" } } } } ], function(err, docs){ if (err){ console.log(err) }else{ console.log(docs) } }) 
+7
mongodb mongoose mongodb-query aggregation-framework
source share
1 answer

Your ids variable will be built from string values, not ObjectId .

Mongoose "autocasts" string values โ€‹โ€‹for ObjectId in their correct type in regular queries, but this does not happen in the aggregation pipeline , as described in issue number 1399.

Instead, you should do the right casting to manually enter:

 ids = ids.map(function(el) { return mongoose.Types.ObjectId(el) }) 

Then you can use them in your pipeline:

 { "$match": { "_id": { "$in": ids } } } 

The reason is that aggregation pipelines โ€œusuallyโ€ change the structure of the document, and therefore mongoose makes no assumptions that the โ€œschemaโ€ applies to the document at any stage of the pipeline.

It can be argued that the stage of the "first" pipeline, when it is the $match stage, should do this, since the document does not really change. But now this is not so.

Any values โ€‹โ€‹that may be "strings" or at least not valid BSON types must be manually added to match.

+12
source share

All Articles