Не можете да върнете множество елементи от масив, отговарящи на вашите критерии под каквато и да е форма на основен .find()
запитване. За да съответствате на повече от един елемент, трябва да използвате .aggregate()
вместо това.
Основната разлика тук е, че "заявката" прави точно това, което е предназначена да направи и съответства на "документи", които отговарят на вашите условия. Можете да опитате да използвате позиционния $
оператор в рамките на проекционен аргумент, но според правилата той ще съответства само на „първия“ елемент на масива, който отговаря на условията на заявката.
За да „филтрирате“ за множество елементи на масива, продължете както следва:
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" }
}}
])
В съвременните версии на MongoDB, които са версия 2.6 или по-нова, можете да направите това с $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"
]
}}
])
Това е може би най-ефективната ви опция, но е рекурсивна, така че първо помислете за структурата на вашия документ, тъй като едно и също име поле не може да съществува с друго условие на което и да е ниво.
Вероятно по-безопасна, но полезна само когато резултатите в масива са "наистина уникални", е тази техника с $map
и $setDifference
:
db.sample.aggregate([
{ "$project": {
"filtermetric": { "$setDifference": [
{ "$map": [
"input": "$filtermetric",
"as": "el",
"in": {"$cond": [
{ "$eq": [ "$$el.class", "s2" ] },
"$$el",
false
]}
]},
[false]
]}
}}
])
Също така отбелязваме, че и в $group
и $project
оперативни етапи на тръбопровод, от които се необходим за да посочите всички полета, които възнамерявате да върнете във вашите документи с резултати от този етап.
Последната бележка е, че $elemMatch
не се изисква, когато питате само стойността на един ключ в масив. "Точковата нотация" е предпочитана и препоръчителна при достъп само до един ключ от масива. $elemMatch
трябва да е необходимо само когато „множество“ ключове в документа в рамките на масива „елемент“ трябва да съответстват на условие на заявка.