MongoDB
 sql >> Baza danych >  >> NoSQL >> MongoDB

MongoDB elemmatch wiele elementów w tablicy

Nie możesz zwrócić wielu elementów tablicy pasujących do twoich kryteriów w żadnej formie podstawowego .find() zapytanie. Aby dopasować więcej niż jeden element, musisz użyć .aggregate() zamiast tego.

Główną różnicą jest to, że „zapytanie” robi dokładnie to, do czego jest przeznaczone, i dopasowuje „dokumenty”, które spełniają Twoje warunki. Możesz spróbować użyć pozycyjnego $ operator w argumencie projekcji, ale istnieją zasady, że będzie on pasował tylko do „pierwszego” elementu tablicy, który pasuje do warunków zapytania.

Aby „przefiltrować” wiele elementów tablicy, wykonaj następujące czynności:

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" }
    }}
])

W nowoczesnych wersjach MongoDB, które są w wersji 2.6 lub nowszej, możesz to zrobić za 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"
        ]
    }}
])

Jest to prawdopodobnie najbardziej wydajna opcja, ale jest ona rekurencyjna, więc najpierw zastanów się nad strukturą dokumentu, ponieważ to samo nazwane pole nie może istnieć z żadnym innym warunkiem na żadnym poziomie.

Prawdopodobnie bezpieczniejsza, ale przydatna tylko wtedy, gdy wyniki w tablicy są „naprawdę unikalne” jest ta technika z $map i $setDifference :

db.sample.aggregate([
    { "$project": {
        "filtermetric": { "$setDifference": [
            { "$map": [
                "input": "$filtermetric",
                "as": "el",
                "in": {"$cond": [
                    { "$eq": [ "$$el.class", "s2" ] },
                    "$$el",
                    false
                ]}
            ]},
            [false]
        ]}
    }}
])

Zauważając również, że w obu $group i $project operacyjne etapy rurociągu, których potrzebujesz aby określić wszystkie pola, które zamierzasz zwrócić w dokumentach wynikowych z tego etapu.

Ostatnia uwaga jest taka, że ​​$elemMatch nie jest wymagane, gdy pytasz tylko o wartość pojedynczego klucza w tablicy. „Notacja kropkowa” jest preferowana i zalecana w przypadku dostępu tylko do jednego klucza tablicy. $elemMatch powinno być potrzebne tylko wtedy, gdy „wiele” kluczy w dokumencie w tablicy „element” musi pasować do warunku zapytania.




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Odświeżanie strony Meteor za pomocą kliknięcia przycisku

  2. Pula połączeń bazy danych MongoDB Java Driver z Tomcat

  3. MongoDB:Jak zaktualizować pojedynczy element podrzędny w tablicy, do którego odwołuje się indeks w tablicy?

  4. mongodb php - jak wykonać zapytanie typu INNER JOIN

  5. Czy w ramach agregacji Mongodb istnieje funkcja dolna?