MongoDB
 sql >> база данни >  >> NoSQL >> MongoDB

MongoDB - $project вложен документ до основно ниво

За MongoDB 3.6 и по-нови, използвайте рамка за агрегиране с $replaceRoot тръбопровод, който може да се прилага във връзка с $mergeObjects оператор като newRoot израз.

Този израз

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

ще обедини полетата от най-високо ниво в документа с тези във вградените полета на поддокумента, така че в крайна сметка вашата обобщена операция ще бъде както следва:

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

В противен случай ще ви трябва механизъм, за да получите всички динамични ключове, които са ви необходими, за да сглобите динамичния $project документ. Това е възможно чрез Map-Reduce . Следната операция mapreduce ще попълни отделна колекция с всички ключове като _id стойности:

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

За да получите списък с всички динамични ключове, изпълнете distinct в получената колекция:

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

Сега като имате предвид списъка по-горе, можете да сглобите своя $project тръбопроводен документ за агрегиране чрез създаване на обект, чиито свойства ще бъдат зададени в рамките на цикъл. Обикновено вашият $project документ ще има следната структура:

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

Така че, използвайки горния списък с ключове на поддокументи, можете динамично да конструирате горното, като използвате reduce() метод:

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. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. По-добър начин за преместване на MongoDB колекция в друга колекция

  2. Колекцията от метеори наблюдава промените правилно

  3. Документно-ориентираните бази данни са предназначени да заменят релационни бази данни?

  4. mongo използва mongoose във възел искате да използвате или и в заявка

  5. как да използвам попълване и агрегиране в едно и също изявление?