sql >> Databáze >  >> NoSQL >> MongoDB

MongoDB elemmatch více prvků v poli

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.




  1. vytvoření registračního a přihlašovacího formuláře v node.js a mongodb

  2. jak zavolat operaci počítání po nálezu pomocí java ovladače mongodb

  3. Jak spustím Mongo DB z Windows?

  4. redis HLL příliš mnoho falešných poplachů