Nemůžete vrátit více prvků pole vyhovujících vašim kritériím v žádné formě základního .find()
dotaz. Chcete-li porovnat více než jeden prvek, musíte použít .aggregate()
místo toho.
Hlavní rozdíl je v tom, že „dotaz“ dělá přesně to, k čemu je určen, a odpovídá „dokumentům“, které splňují vaše podmínky. Můžete zkusit použít poziční $
operátor v argumentu projekce, ale tam platí pravidla, že bude odpovídat pouze "prvnímu" prvku pole, který odpovídá podmínkám dotazu.
Chcete-li "filtrovat" více prvků pole, postupujte následovně:
db.sample.aggregate([
// Filter possible documents
{ "$match": { "filtermetric.class": "s2" } },
// Unwind the array to denormalize
{ "$unwind": "$filtermetric" },
// Match specific array elements
{ "$match": { "filtermetric.class": "s2" } },
// Group back to array form
{ "$group": {
"_id": "$_id",
"filtermetric": { "$push": "$filtermetric" }
}}
])
V moderních verzích MongoDB, které jsou verze 2.6 nebo vyšší, to můžete provést pomocí $redact
:
db.sample.aggregate([
// Filter possible documents
{ "$match": { "filtermetric.class": "s2" } },
// Redact the entries that do not match
{ "$redact": {
"$cond": [
{ "$eq": [ { "$ifNull": [ "$class", "s2" ] }, "s2" ] },
"$$DESCEND",
"$$PRUNE"
]
}}
])
To je pravděpodobně vaše nejúčinnější možnost, ale je rekurzivní, takže nejprve zvažte strukturu dokumentu, protože stejně pojmenované pole nemůže existovat s žádnou jinou podmínkou na žádné úrovni.
Možná bezpečnější, ale užitečná pouze tam, kde jsou výsledky v poli „skutečně jedinečné“, je tato technika s $map
a $setDifference
:
db.sample.aggregate([
{ "$project": {
"filtermetric": { "$setDifference": [
{ "$map": [
"input": "$filtermetric",
"as": "el",
"in": {"$cond": [
{ "$eq": [ "$$el.class", "s2" ] },
"$$el",
false
]}
]},
[false]
]}
}}
])
Všimněte si také, že v obou $group
a $project
provozní fáze potrubí, které potřebujete specifikovat všechna pole, která hodláte vrátit ve výsledných dokumentech z této fáze.
Poslední poznámka je, že $elemMatch
není vyžadován, když se dotazujete pouze na hodnotu jednoho klíče v poli. "Dot notation" je preferovaný a doporučený při přístupu pouze k jednomu klíči pole. $elemMatch
by mělo být potřeba pouze tehdy, když "více" klíčů v dokumentu v rámci "prvku" pole musí odpovídat podmínce dotazu.