Es gibt einen besonderen Trick, wie dies gehandhabt wird, aber erstens, wenn Sie MongoDB 2.6 oder höher zur Verfügung haben, können Sie tatsächlich tun, was Sie wollen, ohne $unwind
. Dies kann für die Leistung sehr praktisch sein, wenn Sie viele Dokumente verarbeiten.
Die wichtigsten Operatoren hier sind $map
der Arrays an Ort und Stelle verarbeitet, und den $allElementsTrue
Operator, der Ihre "Ergebnis"-Felder auswertet. Die Verwendung von „map“ hier ermöglicht sowohl das Testen des inneren „tests“-Arrays, um zu sehen, wo die „result“-Felder darin alle die wahre Bedingung erfüllen. Im Fall des äußeren Arrays kann dieses "Ergebnis" nach Bedarf in diese Dokumente eingefügt werden, und natürlich folgt die vollständige Auswertung für das Dokument denselben Regeln:
db.test.aggregate([
{ "$project": {
"name": 1,
"result": {
"$allElementsTrue": {
"$map": {
"input": "$acts",
"as": "act",
"in": {
"$allElementsTrue": {
"$map": {
"input": "$$act.tests",
"as": "test",
"in": "$$test.result"
}
}
}
}
}
},
"acts": {
"$map": {
"input": "$acts",
"as": "act",
"in": {
"name": "$$act.name",
"result": {
"$allElementsTrue": {
"$map": {
"input": "$$act.tests",
"as": "test",
"in": "$$test.result"
}
}
},
"tests": "$$act.tests"
}
}
}
}}
])
Um dies in früheren Versionen zu tun, müssen Sie $group
in zwei Schritten zurück, um die Arrays "neu aufzubauen", während die Tests für diese "Ergebnis"-Felder erneut durchgeführt werden. Der andere Unterschied hier ist auch die Verwendung des $min
Operator als false
wird als kleinerer Wert als true
betrachtet und wertet nach demselben "allElements"-Konzept aus:
db.test.aggregate([
{ "$unwind": "$acts" },
{ "$unwind": "$acts.tests" },
{ "$group": {
"_id": {
"_id": "$_id",
"name": "$name",
"actName": "$acts.name"
},
"result": { "$min": "$acts.tests.result" },
"tests": {
"$push": {
"name": "$acts.tests.name",
"result": "$acts.tests.result"
}
}
}},
{ "$group": {
"_id": "$_id._id",
"name": { "$first": "$_id.name" },
"result": { "$min": "$result" },
"acts": {
"$push": {
"name": "$_id.actName",
"result": "$result",
"tests": "$tests"
}
}
}}
])