2017-02-11 22 views
2

У меня есть projects коллекцию документов, такие, как это:MongoDB 3.4 - получить массив поддокументов без корневого документа

{ 
     "_id" : ObjectId("589eff3fee3d13019843f55a"), 
     "name" : "Project A", 
     "desc" : "test", 
     "numofvms" : 0, 
     "templates" : [ 
       { 
         "_id" : ObjectId("589e4c14ee3d131bac8b403c") 
       }, 
       { 
         "_id" : ObjectId("589e4c1dee3d131bac8b403d") 
       } 
     ], 
     "nodes" : [ 
       { 
         "_id" : ObjectId("589eff8f2bb59057c3f9b89d"), 
         "name" : "Node A" 
       }, 
       { 
         "_id" : ObjectId("589eff962bb59057c3f9b89e"), 
         "name" : "Node B" 
       }, 
       { 
         "_id" : ObjectId("589eff982bb59057c3f9b89f"), 
         "name" : "Node C" 
       }, 
       { 
         "_id" : ObjectId("589eff9a2bb59057c3f9b8a0"), 
         "name" : "Node D" 
       } 
     ], 
     "links" : [ ] 
} 

Я пытаюсь получить массив поддокументов (nodes поля) для данного документа (проект) , но без корневого документа. Результат должен выглядеть следующим образом:

[ 
     { 
       "_id" : ObjectId("589eff8f2bb59057c3f9b89d"), 
       "name" : "Node A" 
     }, 
     { 
       "_id" : ObjectId("589eff962bb59057c3f9b89e"), 
       "name" : "Node B" 
     }, 
     { 
       "_id" : ObjectId("589eff982bb59057c3f9b89f"), 
       "name" : "Node C" 
     }, 
     { 
       "_id" : ObjectId("589eff9a2bb59057c3f9b8a0"), 
       "name" : "Node D" 
     } 
] 

Я пробовал различные подходы, как показано ниже, но не мог избавиться от корневого документа:

> db.projects.find({_id: ObjectId("589eff3fee3d13019843f55a")}, { "nodes": 1, _id: 0 }).pretty() 
{ 
     "nodes" : [ 
       { 
         "_id" : ObjectId("589eff8f2bb59057c3f9b89d"), 
         "name" : "Node A" 
       }, 
       { 
         "_id" : ObjectId("589eff962bb59057c3f9b89e"), 
         "name" : "Node B" 
       }, 
       { 
         "_id" : ObjectId("589eff982bb59057c3f9b89f"), 
         "name" : "Node C" 
       }, 
       { 
         "_id" : ObjectId("589eff9a2bb59057c3f9b8a0"), 
         "name" : "Node D" 
       } 
     ] 
} 

Может ли это быть достигнуто непосредственно в запросе или я нужно извлечь массив вручную в моем приложении?

ответ

0

Попробуйте это:

db.collection.aggregate([ 
    { 
     $unwind: '$nodes' 
    }, 
    { 
     $match: {_id: ObjectId("589eff3fee3d13019843f55a") } 
    }, 
    { 
     $replaceRoot: { newRoot: "$nodes" } 
    } 
]).toArray(); 

И вы получите

[ 
    { 
     "_id" : ObjectId("589eff8f2bb59057c3f9b89d"), 
     "name" : "Node A" 
    }, 
    { 
     "_id" : ObjectId("589eff962bb59057c3f9b89e"), 
     "name" : "Node B" 
    }, 
    { 
     "_id" : ObjectId("589eff982bb59057c3f9b89f"), 
     "name" : "Node C" 
    }, 
    { 
     "_id" : ObjectId("589eff9a2bb59057c3f9b8a0"), 
     "name" : "Node D" 
    } 
] 

$unwind оператора деконструкция nodes поля из входных документов для вывода документа для каждого элемента.

И затем используйте этап $replaceRoot, чтобы продвинуть документ nodes на верхний уровень, отбрасывая текущие поля верхнего уровня.

Надеюсь, это поможет.

1

Вот как вы можете сделать это с помощью агрегации (Монго v3.4 +):

db.projects.aggregate([ 
 
\t {$match: {_id: ObjectId("589eff3fee3d13019843f55a")}}, 
 
\t {$unwind: '$nodes'}, 
 
\t {$replaceRoot: { newRoot: "$nodes"}} 
 
]).toArray();

Заканчивать the docs.