2017-01-11 51 views
4

該結構或多或少像;

[ 
    {id: 1, name: "alex" , children: [2, 4, 5]}, 
    {id: 2, name: "felix", children: []}, 
    {id: 3, name: "kelly", children: []}, 
    {id: 4, name: "hannah", children: []}, 
    {id: 5, name: "sonny", children: [6]}, 
    {id: 6, name: "vincenzo", children: []} 
] 

我想的名字來代替children ID的時候children數組不爲空。

所以查詢的結果是預期的;

[ {id: 1, name: "alex" , children: ["felix", "hannah" , "sonny"]} 
    {id: 5, name: "sonny", children: ["vincenzo"]} 
] 

我做了什麼來實現這一點;

db.list.aggregate([ 
    {$lookup: { from: "list", localField: "id", foreignField: "children", as: "children" }}, 
    {$project: {"_id" : 0, "name" : 1, "children.name" : 1}}, 
]) 

充滿兒童與其父,這不是我想要的:)

{ "name" : "alex", "parent" : [ ] } 
{ "name" : "felix", "parent" : [ { "name" : "alex" } ] } 
{ "name" : "kelly", "parent" : [ ] } 
{ "name" : "hannah", "parent" : [ { "name" : "alex" } ] } 
{ "name" : "sonny", "parent" : [ { "name" : "alex" } ] } 
{ "name" : "vincenzo", "parent" : [ { "name" : "sonny" } ] } 

我是怎麼誤解?

回答

6

使用前$lookup階段你應該使用$unwind兒童陣列然後$lookup爲兒童。之後$lookup階段,你需要使用$group讓孩子陣列,而不是ID

,您可以嘗試:

db.list.aggregate([ 
    {$unwind:"$children"}, 
    {$lookup: { 
     from: "list", 
     localField: "children", 
     foreignField: "id", 
     as: "childrenInfo" 
     } 
    }, 
    {$group:{ 
     _id:"$_id", 
     children:{$addToSet:{$arrayElemAt:["$childrenInfo.name",0]}}, 
     name:{$first:"$name"} 
     } 
    } 
]); 

// can use $push instead of $addToSet if name can be duplicate 

爲什麼使用$group

例如: 你的第一份文件

{id: 1, name: "alex" , children: [2, 4, 5]} 

$unwind後您的文檔會被像$lookup

{id: 1, name: "alex" , children: 2, 
    "childrenInfo" : [ 
     { 
      "id" : 2, 
      "name" : "felix", 
      "children" : [] 
     } 
    ]}, 
//.... 

{id: 1, name: "alex" , children: 2}, 
{id: 1, name: "alex" , children: 4}, 
{id: 1, name: "alex" , children: 5} 

之後再$group

{id: 1, name: "alex" , children: ["felix", "hannah" , "sonny"]} 
+1

謝謝你的回答。我瞭解我對localField和ForeignField的錯誤。但是你能解釋查詢中的$ group嗎? – mmu36478

+0

因爲'$ unwind' * children *數組使它爲每個* children *分開文檔,然後再使它成爲* children的數組*需要使用'$ group'。可以看到https://docs.mongodb.com/v3.2/reference/operator/aggregation/unwind/#unwind-array –

+0

就像你在每個聚合方法之後顯示當前狀態一樣 - 使得它更容易遵循。 +1 –

3

隨着當前蒙戈3.4版本中,你可以使用$graphLookup

$maxDepth設置爲0進行非遞歸查找。您可能希望在查找之前添加一個$match階段以過濾沒有子項的記錄。

db.list.aggregate([{ 
    $graphLookup: { 
     from: "list", 
     startWith: "$children", 
     connectFromField: "children", 
     connectToField: "id", 
     as: "childrens", 
     maxDepth: 0, 
    } 
}, { 
    $project: { 
     "_id": 0, 
     "name": 1, 
     "childrenNames": "$childrens.name" 
    } 
}]); 
+0

最好的解決方案謝謝 – Vipul

相關問題