Tengo muchas colecciones en mi base de datos MongoDB. El trabajo de agregación es bueno, pero no puedo enviar algunos campos a la salida que necesitaba,
la colección A es:
{ _id: some mongodbID //...fields items: [ { _id: someId, color: someId <---- Im aggregate this with lookup neededFieldToPush: 123 }, { _id: someId, color: someId <---- Im aggregate this with lookup neededFieldToPush: 566 } ] }mi consulta es:
await Invoice.aggregate([ { $match: query }, { $unwind: "$items" }, //colors { $lookup: { from: "colors", localField: "items.itemColor", foreignField: "_id", as: "itemColor" } }, { $addFields: { "prMove.itemColor": { $arrayElemAt: ["$itemColor.colorName", 0] }, } }, { $group: { _id: "$_id", items: { $push: "$items" }, <-- original items prMove: { $push: "$prMove" }, } }, ]) .sort({date: -1}) .skip(+req.query.offset) .limit(+req.query.limit)Necesito tener una salida como esta:
_id: someId, items: [//original items], prMove: [ { itemColor: some color name, <--- it's works fine neededFieldToPush: 123 }, { itemColor: some color name, <--- it's works fine neededFieldToPush: 566 }, ] entonces, ¿cómo puedo insertar el campo neededFieldToPush en el objeto prMove ?
gracias
La implementación de su consulta es costosa porque ha utilizado la etapa $unwind y la etapa $group , afectará el rendimiento,
La segunda cosa es que las funciones $sort , $skip y $limit no funcionarán en la función agregada de mongoose, tiene etapas de uso para eso,
Lo tercero es utilizar las etapas sort, $skip y $limit inmediatamente después de la etapa $match , por lo que mejorará el rendimiento mientras crea un índice en los campos obligatorios.
consulta mejorada,
$match su consulta$sort clasificar etapa de clasificación$skip etapa para pasar compensación$limit para limitar documentos$lookup con la colección de colores y pase items.color como localField$addFields para editar la matriz de items con el nombre del color en items$map para iterar el bucle de la matriz de items$reduce para iterar el ciclo del resultado de la matriz itemColor de la búsqueda, verificar la condición si _id coincide, luego obtener el nombre del color y establecer el valor en el campo de color$mergeObjects para fusionar el nuevo campo de color y los campos actuales del objeto del elemento$$REMOVE para eliminar la matriz itemColor porque ahora no se necesita let offset = req.query.offset; let limit = req.query.limit; await Invoice.aggregate([ { $match: query }, { $sort: { date: -1 } }, { $skip: offset }, { $limit: limit }, { $lookup: { from: "colors", localField: "items.color", foreignField: "_id", as: "itemColor" } }, { $addFields: { items: { $map: { input: "$items", as: "i", in: { $mergeObjects: [ "$$i", { color: { $reduce: { input: "$itemColor", initialValue: "", in: { $cond: [ { $eq: ["$$this._id", "$$i._id"] }, "$$this.colorName", "$$value" ] } } } } ] } } }, itemColor: "$$REMOVE" } } ])