Rientrano nella categoria degli stupidi trucchi di aggregazione è una piccola tecnica che spesso viene trascurata.
La query che esegue tutto il raggruppamento attorno al documento _id, essendo l'identificatore univoco per questo documento. Quindi il punto principale a cui pensare è l'intero documento in realtà è già un identificatore univoco. Quindi, invece di riporre semplicemente la chiave _id, usa l'intero documento.
{$project: {
_id: { _id: "$_id", name: "$name", forms: "$forms" }, forms: "$forms"}
},
In questo caso, tutto ciò che viene arrotolato da _id mantiene il documento nella sua forma originale. Al termine di tutte le altre fasi di aggregazione, emetti un $progetto finale al fine di ripristinare la vera forma del documento originale:
{$project: { _id: "$_id._id", name: "$_id.name", forms: "$_id.forms"}}
Quindi avrai i risultati filtrati che desideri. Questa tecnica può essere molto utile se utilizzata con filtri avanzati come nel caso di questa query, poiché elimina la necessità di emettere un ulteriore trova su tutti i risultati.
Inoltre, nel caso in cui sai che stai solo cercando una serie di risultati che corrispondono a un determinato insieme di condizioni, usa un $match operatore come il primo fase della pipeline di aggregazione. Questo non è solo utile per ridurre le dimensioni del set di lavoro, ma è anche l'unico fase in cui puoi utilizzare un indice e dove puoi aumentare significativamente le prestazioni delle query.
L'intero processo insieme:
db.forms.aggregate([
{$match: { "forms.status": "closed" } },
{$project: {
_id: { _id: "$_id", name: "$name", forms: "$forms" }, forms: "$forms"}
},
{$unwind: "$forms"},
{$group: { _id: "$_id", status: {$addToSet: "$forms.status"}}},
{$unwind: "$status"},
{$sort: { _id: 1, status: -1} },
{$group: { _id: "$_id", status: {$first: "$status"} }},
{$match: { status: "closed"}},
{$project: { _id: "$_id._id", name: "$_id.name", forms: "$_id.forms"}}
])