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

Jak třídit podle „hodnoty“ konkrétního klíče v rámci vlastnosti uložené jako pole s páry k-v v mongodb

Za předpokladu, že to, co chcete, by byly všechny dokumenty, které mají hodnotu „body“ jako „klíč“ v poli, a poté seřadit podle „hodnoty“ pro tento „klíč“, pak je to trochu mimo rozsah .find() metoda.

Důvodem je, pokud jste něco takového udělali

db.collection.find({
    "setid": 154421, "data.k": "point" }
).sort({ "data.v" : -1 })

Problém je, že i když odpovídající prvky dělají mít odpovídající klíč „point“, neexistuje způsob, jak říct, který data.v máte na mysli řazení. Také sort v rámci .find() výsledky neudělají něco takového:

db.collection.find({
    "setid": 154421, "data.k": "point" }
).sort({ "data.$.v" : -1 })

Což by bylo snažení použít poziční operátor v rámci řazení, který v podstatě říká, který prvek má použít hodnotu v na. Ale to není podporováno a pravděpodobně nebude, a pro nejpravděpodobnější vysvětlení, že hodnota "indexu" bude pravděpodobně v každém dokumentu jiná.

Ale tento druh selektivní třídění lze provést pomocí .aggregate() .

db.collection.aggregate([

    // Actually shouldn't need the setid
    { "$match": { "data": {"$elemMatch": { "k": "points" } } } },

    // Saving the original document before you filter
    { "$project": {
        "doc": {
           "_id": "$_id",
           "setid": "$setid",
           "date": "$date",
           "version": "$version",
           "data": "$data"
        },
        "data": "$data"
    }}

    // Unwind the array
    { "$unwind": "$data" },

    // Match the "points" entries, so filtering to only these
    { "$match": { "data.k": "points" } },

    // Sort on the value, presuming you want the highest
    { "$sort": { "data.v": -1 } },

    // Restore the document
    { "$project": {
        "setid": "$doc.setid",
        "date": "$doc.date",
        "version": "$doc.version",
        "data": "$doc.data"
    }} 

])

To samozřejmě předpokládá data pole má pouze jednu prvek, který má klíčové body. Pokud by jich bylo více, museli byste $group před tímto řazením:

    // Group to remove the duplicates and get highest
    { "$group": { 
        "_id": "$doc",
        "value": { "$max": "$data.v" }
    }},

    // Sort on the value
    { "$sort": { "value": -1 } },

    // Restore the document
    { "$project": { 
        "_id": "$_id._id",
        "setid": "$_id.setid",
        "date": "$_id.date",
        "version": "$_id.version",
        "data": "$_id.data"
    }}

Existuje tedy jedno použití .aggregate() s cílem udělat nějaký komplex třídění na dokumentech a přesto vrátit původní výsledek dokumentu v plném rozsahu.

Přečtěte si další informace o operátorech agregace a obecný rámec. Je to užitečný nástroj k učení, který vás zavede za .find() .




  1. Ověření MongoDb pomocí Hibernate OGM

  2. Nelze spustit sadu replik v Ubuntu

  3. nelze spustit kontejner mongoDb v dockeru pro Windows pomocí souborového systému linux

  4. Rychlejší metoda pro přesun dat redis do MySQL