sql >> Database >  >> NoSQL >> MongoDB

Aggregatie gebruiken om te sorteren in complexe voorwaardelijke in Mongodb

Merk eerst op dat uw sorteervoorbeeld onjuist is gevormd:de aggregatiemethode neemt een array als invoer, waarbij elk element in de array een fase in een aggregatiepijplijn specificeert. Merk ook op dat de $elemMatch operator kan niet worden gebruikt als onderdeel van een $sort-fase.

Een manier om te bereiken wat u probeert te doen met uw sorteervoorbeeld is het gebruik van het aggregatieraamwerk $ontspan pijpleiding exploitant. Als u een array afwikkelt, worden de array-elementen één voor één verwijderd in afzonderlijke documenten. Bijvoorbeeld de volgende vraag

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

geeft iets als het volgende terug:

[
    {
        "_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"
        }
    }
]

Door een $match-fase toe te voegen, kunt u alleen de documenten pakken waar answer.id nul is. Ten slotte kunt u met een $sort-fase sorteren op answer.value. Alles bij elkaar is de aggregatiequery:

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

En de uitvoer:

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

Op basis van wat je vraagt, klinkt het niet alsof je altijd $unwind of zelfs het aggregatieraamwerk nodig hebt. Als u in plaats daarvan het document wilt vinden met answer.id gelijk aan 0 en answer.value gelijk aan 3,5, en dan answer.value wilt wijzigen in 4, kunt u find gebruiken met $elemMatch gevolgd door 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. Hoe de Meteor MongoDB-versie op lokaal specificeren?

  2. Hoe u terugbellen in mangoest instelt, in een globale variabele

  3. Spring RedisTemplate:serialiseer meerdere modelklassen in JSON. Wilt u meerdere RedisTemplates gebruiken?

  4. Hoe te voorkomen dat meerdere documenten aan de mongodb-database worden toegevoegd?