Hay un truco particular sobre cómo se maneja esto, pero en primer lugar, si tiene MongoDB 2.6 o superior disponible, puede hacer lo que quiera sin usar $unwind
. Esto puede ser muy útil para el rendimiento si está procesando muchos documentos.
Los operadores clave aquí son $map
que procesa arreglos en su lugar y el $allElementsTrue
operador que evaluará sus campos de "resultado". El uso de "mapa" aquí permite la prueba de la matriz de "pruebas" interna para ver dónde los campos de "resultado" allí cumplen la condición verdadera. En el caso de la matriz externa, este "resultado" se puede colocar en los documentos que necesite y, por supuesto, la evaluación completa del documento sigue las mismas reglas:
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"
}
}
}
}}
])
La forma de hacerlo en versiones anteriores requiere que $group
retroceda en dos pasos para "reconstruir" las matrices mientras realiza las pruebas en esos campos de "resultado" nuevamente. La otra diferencia aquí también es usar $min
operador como false
se considerará un valor menor que true
y evalúa el mismo concepto "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"
}
}
}}
])