sql >> Database >  >> NoSQL >> MongoDB

MongoDB - $project genest document naar hoofdniveau

Gebruik voor MongoDB 3.6 en nieuwer een aggregatieframework met een $replaceRoot pijplijn die kan worden toegepast in combinatie met de $mergeObjects operator als de newRoot uitdrukking.

Deze uitdrukking

{ "$mergeObjects": ["$subdoc", "$$ROOT"] }

zal de velden op het hoogste niveau in het document samenvoegen met die in de ingesloten velden van het subdoc, zodat uw totale bewerking uiteindelijk als volgt zal zijn:

db.collection.aggregate([
    { "$replaceRoot": { 
        "newRoot": { 
            "$mergeObjects": [ "$subdoc", "$$ROOT" ] 
        } 
    } },
    { "$project": { "subdoc": 0 } }  
])

Anders zou je een mechanisme nodig hebben om alle dynamische sleutels te krijgen die je nodig hebt om het dynamische $project samen te stellen document. Dit is mogelijk via Map-Reduce . De volgende mapreduce-bewerking zal een aparte verzameling vullen met alle sleutels als de _id waarden:

mr = db.runCommand({
    "mapreduce": "my_collection",
    "map" : function() {
        for (var key in this.subdoc) { emit(key, null); }
    },
    "reduce" : function(key, stuff) { return null; }, 
    "out": "my_collection" + "_keys"
})

Om een ​​lijst van alle dynamische sleutels te krijgen, voer je het volgende uit op de resulterende verzameling:

db[mr.result].distinct("_id")
["field2", "field3", ...]

Gezien de bovenstaande lijst, kunt u uw $project . samenstellen aggregatiepijplijndocument door een object te maken waarvan de eigenschappen binnen een lus worden ingesteld. Normaal gesproken is uw $project document heeft deze structuur:

var project = {
    "$project": {
        "field1": 1,
        "field2": "$subdoc.field2",
        "field3": "$subdoc.field3"
    }
};

Dus met behulp van de bovenstaande lijst met subdocumentsleutels, kunt u het bovenstaande dynamisch construeren met behulp van JavaScript's reduce() methode:

var subdocKeys = db[mr.result].distinct("_id"),
    obj = subdocKeys.reduce(function (o, v){
      o[v] = "$subdoc." + v;
      return o;
    }, { "field1": 1 }),
    project = { "$project": obj };

db.collection.aggregate([project]);



  1. Mongo-fout op I control hotfix

  2. Een geneste record in mongodb-array bijwerken als u de documentindex niet kent

  3. Hoe resque-werknemers in te zetten in productie?

  4. mongodb en authenticeren en paspoort in node.js