2013-10-17 9 views
10

Mam dokument podobny do następującego, gdzie chcę zwróci wszystkie subklatek bieżącego pola najwyższego poziomu jak najlepszych pól szczebla w każdym dokumencie tablicy wyników:Czy mogę łatwo zwrócić wszystkie pola dokumentu podrzędnego jako pola w dokumencie najwyższego poziomu za pomocą struktury agregacji?

{ 
    field1:{ 
      subfield:{} 
      subfield2: [] 
      subfield3: 44 
      subfield5: xyz 

     } 
    field2:{othercontent:{}} 
} 

I chcę, aby wyniki mojej kwerendy agregującej zwróciły następujące rzeczy (zawartość "pola 1" jako dokumentu najwyższego poziomu).

{ 
    subfield:{} 
    subfield2: [] 
    subfield3: 44 
    subfield5: xyz 
} 

Czy można to zrobić za pomocą $ project i struktury agregacji bez definiowania każdego subpola, aby powrócić jako pole najwyższego poziomu? Mam nadzieję, że istnieje skrócona metoda określania, że ​​dokument pod "field1" jest zwracany jako dokument najwyższego poziomu w tablicy wyników.

+2

Jestem ciekaw, czy to możliwe; Myślę, że to nie jest. To pytanie wydaje się być powiązane: http://stackoverflow.com/q/19431773/390819 – GolfWolf

Odpowiedz

1

Generalnie trudno jest zmusić MongoDB do radzenia sobie z niejednoznacznymi lub sparametryzowanymi kluczami json. Wpadłem na similar issue, a najlepszym rozwiązaniem było zmodyfikowanie schematu tak, aby członkowie poddokumentu stali się elementami w tablicy.

Jednak myślę, że to zbliży Cię do tego, co chcesz (cały kod powinien działać bezpośrednio w powłoce Mongo). Zakładając, że dokumenty takie jak:

db.collection.insert({ 
    "_id": "doc1", 
    "field1": { 
      "subfield1": {"key1": "value1"}, 
      "subfield2": ["a", "b", "c"], 
      "subfield3": 1, 
      "subfield4": "a" 
     }, 
    "field2": "other content" 
}) 

db.collection.insert({ 
    "_id": "doc2", 
    "field1": { 
      "subfield1": {"key2": "value2"}, 
      "subfield2": [1, 2, 3], 
      "subfield3": 2, 
      "subfield4": "b" 

     }, 
    "field2": "yet more content" 
}) 

Następnie można uruchomić komendę agregacji, która promuje treści field1 ignorując resztę dokumentu:

db.collection.aggregate({ 
"$group":{ 
    "_id": "$_id", 
    "value": {"$push": "$field1"} 
}}) 

To sprawia, że ​​wszystkie subfield* klucze język TOP- poziomy pól obiektu, a ten obiekt jest jedynym elementem w tablicy. Jest niezdarny, ale wykonalne:

"result" : [ 
     { 
       "_id" : "doc2", 
       "value" : [ 
         { 
           "subfield1" : {"key2" : "value2"}, 
           "subfield2" : [1, 2, 3], 
           "subfield3" : 2, 
           "subfield4" : "b" 
         } 
       ] 
     }, 
     { 
       "_id" : "doc1", 
       "value" : [ 
         { 
           "subfield1" : {"key1" : "value1"}, 
           "subfield2" : ["a","b","c"], 
           "subfield3" : 1, 
           "subfield4" : "a" 
         } 
       ] 
     } 
], 
"ok" : 1 
+0

To nie spełnia wymagań pytania. Dokument wyjściowy ma inny kształt. –

3

Można użyć $replaceRoot operator agregacji od 3,4:

db.getCollection('sample').aggregate([ 
    { 
     $replaceRoot: {newRoot: "$field1"} 
    } 
]) 

Zapewnia wyjście zgodnie z oczekiwaniami:

{ 
    "subfield" : {}, 
    "subfield2" : [], 
    "subfield3" : 44, 
    "subfield5" : "xyz" 
} 
Powiązane problemy