sql >> Database teknologi >  >> NoSQL >> MongoDB

MongoDB - $project indlejret dokument til rodniveau

For MongoDB 3.6 og nyere skal du bruge aggregeringsramme med en $replaceRoot pipeline, der kan anvendes i forbindelse med $mergeObjects operator som newRoot udtryk.

Dette udtryk

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

vil flette felterne på øverste niveau i dokumentet med dem i de indlejrede underdoc-felter, så din samlede operation i sidste ende vil være som følger:

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

Ellers ville du have brug for en mekanisme til at få alle de dynamiske nøgler, du skal bruge for at samle det dynamiske $project dokument. Dette er muligt gennem Map-Reduce . Den følgende mapreduce-operation vil udfylde en separat samling med alle nøglerne som _id værdier:

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

For at få en liste over alle de dynamiske nøgler skal du køre distinkt på den resulterende samling:

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

Nu givet listen ovenfor, kan du samle dit $project aggregeringspipelinedokument ved at skabe et objekt, der vil have dets egenskaber indstillet i en loop. Normalt dit $project dokument vil have denne struktur:

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

Så ved at bruge ovenstående liste over underdokumentnøgler kan du dynamisk konstruere ovenstående ved hjælp af JavaScripts reduce() metode:

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. Punktnotation vs. $elemMatch

  2. $concat felt med indeks i $map mongodb?

  3. Mongoose-forespørgsler om datotilstand har ingen resultater, MongoDB Shell virker

  4. Mongoose String til ObjectID