mmu*_*478 8 lookup mongodb aggregation-framework
结构或多或少像;
[
{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: []}
]
Run Code Online (Sandbox Code Playgroud)
children当children数组不为空时,我想用名称替换id .
所以查询的结果是预期的;
[ {id: 1, name: "alex" , children: ["felix", "hannah" , "sonny"]}
{id: 5, name: "sonny", children: ["vincenzo"]}
]
Run Code Online (Sandbox Code Playgroud)
我做了什么来实现这一目标;
db.list.aggregate([
{$lookup: { from: "list", localField: "id", foreignField: "children", as: "children" }},
{$project: {"_id" : 0, "name" : 1, "children.name" : 1}},
])
Run Code Online (Sandbox Code Playgroud)
用它的父母填充孩子,这不是我想要的:)
{ "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" } ] }
Run Code Online (Sandbox Code Playgroud)
我误解了什么?
Sha*_*Roy 10
在使用$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
Run Code Online (Sandbox Code Playgroud)
为何使用$group?
例如:您的第一份文件
{id: 1, name: "alex" , children: [2, 4, 5]}
Run Code Online (Sandbox Code Playgroud)
在$unwind你的文件看起来像
{id: 1, name: "alex" , children: 2},
{id: 1, name: "alex" , children: 4},
{id: 1, name: "alex" , children: 5}
Run Code Online (Sandbox Code Playgroud)
后 $lookup
{id: 1, name: "alex" , children: 2,
"childrenInfo" : [
{
"id" : 2,
"name" : "felix",
"children" : []
}
]},
//....
Run Code Online (Sandbox Code Playgroud)
然后 $group
{id: 1, name: "alex" , children: ["felix", "hannah" , "sonny"]}
Run Code Online (Sandbox Code Playgroud)
使用当前的 Mongo 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"
}
}]);
Run Code Online (Sandbox Code Playgroud)