$ aggregation和$查找同一个集合 - mongodb

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)

childrenchildren数组不为空时,我想用名称替换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)


use*_*814 5

使用当前的 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)