Der er et særligt trick til, hvordan dette håndteres, men for det første, hvis du har MongoDB 2.6 eller nyere tilgængelig, så kan du faktisk gøre, hvad du vil uden at bruge $unwind
. Dette kan være meget praktisk for ydeevnen, hvis du behandler mange dokumenter.
Nøgleoperatørerne her er $map
som behandler arrays på plads og $allElementsTrue
operatør, som vil evaluere dine "resultat" felter. Brugen af "kort" her tillader både test af det indre "test"-array for at se, hvor "resultat"-felterne derinde alle opfylder den sande betingelse. I det ydre array-tilfælde kan dette "resultat" placeres i de dokumenter, som du har brug for, og selvfølgelig følger den fulde evaluering af dokumentet de samme regler:
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"
}
}
}
}}
])
Måden at gøre dette på i tidligere versioner kræver, at du $gruppe
tilbage i to trin for at "genopbygge" arrays, mens du udfører testene på disse "resultat" felter igen. Den anden forskel her er også at bruge $min
operator som falsk
vil blive betragtet som en mindre værdi end true
og evaluerer til det samme "allElements"-koncept:
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"
}
}
}}
])