sql >> Database teknologi >  >> NoSQL >> MongoDB

MongoDB elemmatch flere elementer i array

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.




  1. Hvordan bestemmer man Redis-hukommelseslækage?

  2. Implementering af paginering i mongodb

  3. Redis sentinels i samme servere som master/slave?

  4. Java+Redis vs almindelig Java-effektivitet til dataintensive applikationer?