with mongodb mongoose mongodb-query aggregation-framework

mongodb - with - Moongoose agregado $ match no coincide con los id



match with object id mongoose (1)

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

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

"_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 consulta $in , devuelve una 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 ids se construirá con "cadenas" y no con valores ObjectId .

La mangosta "autocasts" valores de cadena para ObjectId en su tipo correcto en consultas regulares, pero esto no sucede en la canalización de agregación , como se describe en el número 1399.

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

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

Luego puede usarlos en su etapa de tubería:

{ "$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 mangosta no presupone que el "esquema" se aplica al documento en cualquier etapa de la tubería.

Es discutible que la "primera" etapa de canalización 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 BSON correcto debe ser emitido manualmente para que coincida.