MongoDB
 sql >> Baza danych >  >> NoSQL >> MongoDB

MongoDB - $project zagnieżdżony dokument na poziomie głównym

W przypadku MongoDB 3.6 i nowszych użyj struktury agregacji z $replaceRoot potok, który można zastosować w połączeniu z $mergeObjects operator jako newRoot wyrażenie.

To wyrażenie

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

połączy pola najwyższego poziomu w dokumencie z polami osadzonymi w poddokumencie, więc na końcu Twoja agregacja będzie wyglądać następująco:

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

W przeciwnym razie potrzebowałbyś mechanizmu, aby uzyskać wszystkie klucze dynamiczne potrzebne do złożenia dynamicznego $project dokument. Jest to możliwe dzięki Map-Reduce . Następująca operacja mapreduce spowoduje wypełnienie oddzielnej kolekcji wszystkimi kluczami jako _id wartości:

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

Aby uzyskać listę wszystkich kluczy dynamicznych, uruchom odrębnie w wynikowej kolekcji:

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

Teraz, biorąc pod uwagę powyższą listę, możesz złożyć swój $project dokument potoku agregacji, tworząc obiekt, który będzie miał swoje właściwości ustawione w pętli. Zwykle Twój $project dokument będzie miał następującą strukturę:

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

Korzystając z powyższej listy kluczy dokumentów podrzędnych, możesz dynamicznie skonstruować powyższe za pomocą reduce() metoda:

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. Przypadki użycia NoSQL

  2. Meteor:znajdowanie obiektu z kolekcji według _id

  3. Zapytanie o dokumenty, w których rozmiar tablicy jest większy niż 1

  4. Szybkie stronicowanie z MongoDB

  5. Zapytanie agregujące MongoDB — zmiana nazw pól zwracanych z osadzonych dokumentów