Há um truque específico para lidar com isso, mas primeiro, se você tiver o MongoDB 2.6 ou superior disponível, poderá fazer o que quiser sem usar
$unwind
. Isso pode ser muito útil para o desempenho se você estiver processando muitos documentos. Os principais operadores aqui são
$map
que processa arrays no local e o $allElementsTrue
operador que avaliará seus campos de "resultado". O uso de "map" aqui permite tanto o teste do array "tests" interno para ver onde os campos "result" ali atendem à condição verdadeira. No caso da matriz externa, esse "resultado" pode ser colocado nesses documentos conforme você precisar e, é claro, a avaliação completa do documento segue as mesmas regras: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"
}
}
}
}}
])
A maneira de fazer isso em versões anteriores exige que você
$grupo
de volta em duas etapas para "reconstruir" as matrizes enquanto faz os testes nesses campos de "resultado" novamente. A outra diferença aqui também é usar o $min
operador como false
será considerado um valor menor que true
e avalia para o mesmo conceito "allElements":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"
}
}
}}
])