Il existe une astuce particulière pour gérer cela, mais tout d'abord, si vous disposez de MongoDB 2.6 ou d'une version supérieure, vous pouvez réellement faire ce que vous voulez sans utiliser $unwind
. Cela peut être très pratique pour les performances si vous traitez beaucoup de documents.
Les opérateurs clés ici sont $map
qui traite les tableaux en place et le $allElementsTrue
opérateur qui évaluera vos champs "résultat". L'utilisation de "map" ici permet à la fois de tester le tableau interne "tests" pour voir où les champs "result" répondent tous à la vraie condition. Dans le cas du tableau externe, ce "résultat" peut être placé dans ces documents selon vos besoins, et bien sûr l'évaluation complète du document suit les mêmes règles :
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"
}
}
}
}}
])
Pour ce faire, dans les versions antérieures, vous devez $group
revenir en deux étapes afin de "reconstruire" les tableaux tout en refaisant les tests sur ces champs "résultats". L'autre différence ici est également d'utiliser le $min
opérateur comme false
sera considéré comme une valeur inférieure à true
et évalue le même concept "tous les éléments":
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"
}
}
}}
])