Tengo dos colecciones Course y File . Estos son mis datos de la colección del Course
[{ _id: 1, name: "Course1", price: "100" }, { _id: 2, name: "Course2", price: "200" }]Estos son mis datos de la colección de archivos.
[{ _id: 1, name: "File1", isFree: true, courseId: 1 } { _id: 2, name: "File2", isFree: false, courseId: 1 } { _id: 3, name: "File3", isFree: false, courseId: 1 }] Quiero recuperar el Curso 1 con Course name del curso, Count of files which are free , Count of files which are not free .
Mi intento:
Course.aggregate([ {$lookup:{ from:"files", localField: "_id", foreignField: "courseId", as: "files" }}, ])Esta es mi respuesta si ejecuto mi consulta anterior:
[ { "_id": "6161bdcc0aada09d81598840", "name": "Course1", "files": [ { "_id": "6166a0814ad3f56b71232b9c", "name": "File1.jpeg", "isFree":true }, { "_id": "6166a0814ad3f56b71232b9d", "name": "File2.jpeg", "isFree":false }, { "_id": "6166a0814ad3f56b71232b9v", "name": "File3.jpeg", "isFree":false } ] } ]Quiero mi salida como:
[ { "_id": "6161bdcc0aada09d81598840", "name": "Course1", "files": {"free": 1,"paid": 2} } ]Puede intentar buscar con canalización,
$lookup con canalización, pase courseId del curso en let$match con la condición de courseId de curso$group por isFeee y obtener el recuento total$project para mostrar los campos obligatorios en formato k(clave) y v(valor)$cond para verificar si isFree es verdadero y luego devolver "gratis"; de lo contrario, devolver "pagado"$addFields para actualizar la matriz de files$arrayToObject convierte files de matriz de valores clave en un objeto$ifNull para verificar si la propiedad no existe y luego establecer 0 await Course.aggregate([ { $lookup: { from: "files", let: { courseId: "$_id" }, pipeline: [ { $match: { $expr: { $eq: ["$$courseId", "$courseId"] } } }, { $group: { _id: "$isFree", count: { $sum: 1 } } }, { $project: { _id: 0, k: { $cond: ["$_id", "free", "paid"] }, v: "$count" } } ], as: "files" } }, { $addFields: { files: { $arrayToObject: "$files" } } }, { $addFields: { "files.free": { $ifNull: ["$files.free", 0] }, "files.paid": { $ifNull: ["$files.paid", 0] } } } ])Intenta lo siguiente:
db.course.aggregate([ { $lookup: { from: "files", localField: "_id", foreignField: "courseId", as: "files", }, }, { $unwind: { path: "$files", preserveNullAndEmptyArrays: true, }, }, { $group: { _id: "$_id", name: { $first: "$name", }, price: { $first: "$price", }, free: { $sum: { $cond: [ { $eq: ["$files.isFree", true], }, 1, 0, ], }, }, paid: { $sum: { $cond: [ { $eq: ["$files.isFree", false], }, 1, 0, ], }, }, }, }, { $addFields: { "files.free": "$free", "files.paid": "$paid", }, }, { $project: { _id: 1, name: 1, files: 1, price: 1, }, }, ]);