sql >> Databasteknik >  >> NoSQL >> MongoDB

Använda aggregering för att sortera i komplex villkorlig i Mongodb

Observera först att ditt sorteringsexempel är felaktigt:aggregeringsmetoden tar en array som indata, där varje element i arrayen anger ett steg i en aggregeringspipeline. Observera också att $elemMatch operatorn kan inte användas som en del av ett $sort-steg.

Ett sätt att uppnå det du försöker göra med ditt sorteringsexempel är att använda aggregeringsramverkets $avslappnade rörledningsoperatör. Om du lindar upp en array kommer arrayelementen att dras av ett och ett till separata dokument. Till exempel följande fråga

db.my_collection.aggregate([ {$unwind: "$answers"} ]);

returnerar något i stil med följande:

[
    {
        "_id" : ObjectId("5237157f3fac8e36fdb0b96e"),
        "user" : "bruno",
        "answers" : {
            "id" : 0,
            "value" : 3.5
        }
    },
    {
        "_id" : ObjectId("5237157f3fac8e36fdb0b96e"),
        "user" : "bruno",
        "answers" : {
            "id" : 1,
            "value" : "hello"
        }
    },
    {
        "_id" : ObjectId("523715813fac8e36fdb0b96f"),
        "user" : "bruno2",
        "answers" : {
            "id" : 0,
            "value" : 0.5
        }
    },
    {
        "_id" : ObjectId("523715813fac8e36fdb0b96f"),
        "user" : "bruno2",
        "answers" : {
            "id" : 1,
            "value" : "world"
        }
    }
]

Genom att lägga till en $match-fas kan du bara ta tag i de dokument där answers.id är noll. Slutligen låter en $sort-fas dig sortera efter answers.value. Sammantaget är aggregeringsfrågan:

db.my_collection.aggregate([
    {$unwind: "$answers"},
    {$match: {"answers.id": 0}},
    {$sort: {"answers.value": -1}}
]);

Och utdata:

[
    {
        "_id" : ObjectId("5237157f3fac8e36fdb0b96e"),
        "user" : "bruno",
        "answers" : {
            "id" : 0,
            "value" : 3.5
        }
    },
    {
        "_id" : ObjectId("523715813fac8e36fdb0b96f"),
        "user" : "bruno2",
        "answers" : {
            "id" : 0,
            "value" : 0.5
        }
    }
]

Baserat på vad du frågar, låter det inte som att du alltid behöver $unwind eller ens aggregeringsramverket. Om du istället ville hitta dokumentet med answers.id lika med 0 och answers.value lika med 3,5 och sedan ändra answers.value till 4 kan du använda find med $elemMatch följt av db.collection.save():

doc = db.my_collection.findOne({"answers": {$elemMatch: {"id": 0, "value": 3.5}}});
for (i=0; i<doc.answers.length; i++) {
  if (doc.answers[i].id === 0) {
    doc.answers[i].value = 4;
    db.my_collection.save(doc);
    break;
  }
}



  1. Utbildning misslyckades - AWS Machine Learning

  2. Hur gör man flera textsökningar med $text query och $or i mongodb / mongoose?

  3. Upserting i Mongo DB och Id-problemet

  4. Golang mongodb aggregering