Moongoose aggregate $ match no coincide con el id

Quiero mostrar los productos por ids ( 56e641d4864e5b780bb992c6 y 56e65504a323ee0812e511f2 ) y mostrar el precio después de restarlo por descuento si está disponible.

Puedo contar el precio final utilizando agregado, pero esto devuelve todos los documentos de una colección, cómo hacer que devuelva solo los ID de los partidos

 "_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) 

esta es mi consulta

 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) } }) 

y si agrego esta $in consulta, devuelve matriz vacía

 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) } }) 

Su variable de ids se construirá con “cadenas” y no con los valores de ObjectId .

Mongoose “autodetecta” valores de cadena para ObjectId en su tipo correcto en consultas regulares, pero esto no ocurre en la canalización de agregación , como se describe en el número 1399.

En su lugar, debe hacer la conversión correcta para escribir manualmente:

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

Entonces puedes usarlos en tu etapa de tramitación:

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

La razón es porque las tuberías de agregación “típicamente” alteran la estructura del documento, y por lo tanto, la mongoose no presupone que el “esquema” se aplica al documento en cualquier etapa de canalización dada.

Es discutible que la “primera” etapa del gasoducto cuando es una etapa de $match debería hacer esto, ya que de hecho el documento no se altera. Pero en este momento no es así como sucede.

Cualquier valor que pueda ser “cadenas” o al menos no el tipo correcto de BSON debe ser lanzado manualmente para que coincida.