Existuje zvláštní trik, jak se s tím zacházet, ale za prvé, pokud máte k dispozici MongoDB 2.6 nebo vyšší, můžete skutečně dělat, co chcete, aniž byste použili $unwind
. To může být velmi užitečné pro výkon, pokud zpracováváte velké množství dokumentů.
Klíčovými operátory jsou zde $map
který zpracovává pole na místě a $allElementsTrue
operátor, který vyhodnotí vaše „výsledková“ pole. Použití "map" zde umožňuje jak testování vnitřního "testů" pole, abychom viděli, kde všechna "výsledková" pole splňují skutečnou podmínku. V případě vnějšího pole lze tento "výsledek" umístit do těchto dokumentů, jak požadujete, a samozřejmě úplné vyhodnocení dokumentu se řídí stejnými pravidly:
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"
}
}
}
}}
])
Způsob, jak to provést v dřívějších verzích, vyžaduje, abyste $group
zpět ve dvou krocích, aby bylo možné pole „znovu sestavit“ a znovu provést testy na těchto polích „výsledků“. Dalším rozdílem je také použití $min
operátor jako false
bude považována za hodnotu nižší než true
a vyhodnotí se podle stejného konceptu "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"
}
}
}}
])