J'ai plusieurs documents et j'essaie d'agréger tous les documents avec companyId = xxx et de renvoyer un tableau avec tous les statuts.
Cela ressemblera donc à ceci:
[ { "companyId": "xxx", "position": "", "section": "", "comment": "", "items": [ { "any": "111", "name": "some name", "description": "some description", "version": "3", "status": [ { "status": "created", "date": "2019-03-16T10:59:59.200Z" }, { "status": "completed", "date": "2019-03-16T11:00:37.750Z" } ] }, { "any": "222", "name": "some name", "description": "some description", "version": "3", "status": [ { "status": "created", "date": "2019-03-16T10:59:59.200Z" }, { "status": "completed", "date": "2019-03-16T11:00:37.750Z" } ] } ] }, { "companyId": "xxx", "position": "", "section": "", "comment": "", "items": [ { "any": "111", "name": "some name", "description": "some description", "version": "3", "status": [ { "status": "created", "date": "2019-03-16T10:59:59.200Z" }, { "status": "completed", "date": "2019-03-16T11:00:37.750Z" } ] }, { "any": "222", "name": "some name", "description": "some description", "version": "3", "status": [ { "status": "created", "date": "2019-03-16T10:59:59.200Z" }, { "status": "completed", "date": "2019-03-16T11:00:37.750Z" } ] } ] }
3 Réponses :
Vous pouvez utiliser l'agrégation ci-dessous:
db.col.aggregate([ { $match: { companyId: "xxx" } }, { $unwind: "$items" }, { $unwind: "$items.status" }, { $replaceRoot: { newRoot: "$items.status" } }, { $group: { _id: "$status", count: { $sum: 1 } } } ])
Double $ unwind renverra un seul statut par document et vous pourrez ensuite utiliser $ replaceRoot pour promouvoir chaque statut au niveau racine de votre document.
De plus, vous pouvez ajouter $ group pour compter les documents par status
.
En plus de la réponse @mickl, vous pouvez ajouter un pipeline $ project
pour obtenir le résultat sous forme de liste plate de statuts et de décomptes.
db.collectionName.aggregate([ { $match: { companyId: "xxx" } }, { $unwind: "$items" }, { $unwind: "$items.status" }, { $replaceRoot: { newRoot: "$items.status" } }, { $group: { _id: "$status", count: { $sum: 1 } } }, { $project: { "status":"$_id", "count":1, _id:0 } } ])
Si le nombre de documents sur lesquels vous exécutez la requête ci-dessus est trop élevé, vous devez éviter d'utiliser $ unwind dans la phase initiale du pipeline d'agrégation.
Soit vous devez utiliser $ project après $ match pour réduire la sélection de champs, soit vous pouvez utiliser la requête ci-dessous:
db.col.aggregate([ { $match: { companyId: "xxx" } }, { $project: { _id: 0, data: { $reduce: { input: "$items.status", initialValue: [ ], in: { $concatArrays: [ "$$this", "$$value" ] } } } } }, { $unwind: "$data" }, { $replaceRoot: { newRoot: "$data" } } ])