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

Jak sortować według „wartości” określonego klucza we właściwości przechowywanej jako tablica z parami k-v w mongodb

Zakładając, że chcesz, aby były wszystkie dokumenty, które mają wartość „punkty” jako „klucz” w tablicy, a następnie sortuj według „wartości” dla tego „klucza”, to jest to trochę poza zakresem .find() metoda.

Powodem jest to, że zrobiłeś coś takiego

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

Problem polega na tym, że chociaż dopasowane elementy do mają pasujący klucz „punkt”, nie ma sposobu, aby powiedzieć, który data.v masz na myśli dla tego rodzaju. Również sort w .find() wyniki nie zrobią czegoś takiego:

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

Który byłby próbował aby użyć operatora pozycyjnego w sortowaniu, zasadniczo mówiącego, który element ma użyć wartości v na. Ale to nie jest obsługiwane i prawdopodobnie nie będzie, a dla najbardziej prawdopodobnego wyjaśnienia ta wartość „indeksu” byłaby prawdopodobnie inna w każdym dokumencie.

Ale tego rodzaju selektywne sortowanie może odbywać się za 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"
    }} 

])

Oczywiście zakłada to data tablica ma tylko jeden element, który ma kluczowe punkty. Gdyby było więcej niż jeden, musiałbyś $group przed czymś takim:

    // 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"
    }}

Jest więc jedno użycie .aggregate() w celu wykonania złożonego sortowanie dokumentów i zwracanie oryginalnego wyniku dokumentu w całości.

Przeczytaj więcej o operatorach agregacji oraz ogólne ramy. To przydatne narzędzie do nauki, które zabierze Cię poza .find() .




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. MongoDB Duplikaty dokumentów nawet po dodaniu unikalnego klucza

  2. node.js &express - globalne moduły i najlepsze praktyki dotyczące struktury aplikacji

  3. Unikaj zduplikowanych wpisów w tablicy Mongoose

  4. Nowość w MongoDB Nie można uruchomić polecenia mongo

  5. Konfigurowanie oauth2-server-laravel za pomocą laravel-mongodb