Du kan ikke returnere flere elementer i et array, der matcher dine kriterier i nogen form for en grundlæggende .find()
forespørgsel. For at matche mere end ét element skal du bruge .aggregate()
metode i stedet.
Den største forskel her er, at "forespørgslen" gør præcis, hvad den er beregnet til, og matcher "dokumenter", der opfylder dine betingelser. Du kan prøve at bruge den positionelle $
operator i et projektionsargument, men reglerne der er, at det kun vil matche det "første" array-element, der matcher forespørgselsbetingelserne.
For at "filtrere" for flere array-elementer, fortsæt som følger:
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" }
}}
])
I moderne versioner af MongoDB, der er version 2.6 eller nyere, kan du gøre dette med $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"
]
}}
])
Det er nok din mest effektive mulighed, men den er rekursiv, så overvej først din dokumentstruktur, da det samme navngivne felt ikke kan eksistere med nogen anden betingelse på noget niveau.
Muligvis sikrere, men kun nyttig, hvor resultaterne i arrayet er "virkelig unikke", er denne teknik med $map
og $setDifference
:
db.sample.aggregate([
{ "$project": {
"filtermetric": { "$setDifference": [
{ "$map": [
"input": "$filtermetric",
"as": "el",
"in": {"$cond": [
{ "$eq": [ "$$el.class", "s2" ] },
"$$el",
false
]}
]},
[false]
]}
}}
])
Bemærk også, at i både $group
og $project
operationelle pipeline stadier du bruger for for at angive alle de felter, du agter at returnere i dine resultatdokumenter fra det tidspunkt.
Den sidste bemærkning er, at $elemMatch
er ikke påkrævet, når du kun forespørger på værdien af en enkelt nøgle i et array. "Dot notation" foretrækkes og anbefales, når der kun er adgang til en enkelt nøgle i arrayet. $elemMatch
bør kun være nødvendig, når "flere" nøgler i dokumentet i arrayet "element" skal matche en forespørgselsbetingelse.