RaR*_*RaR 13 tree-structure mongodb aggregation-framework
我在MongoDB中有一个带有树结构的文档列表,其中使用了带有父引用模型的模型树结构.我想要一个聚合查询,它返回祖先列表(直到根),给定'name'属性.
结构体:
{
  '_id': '1',
  'name': 'A',
  'parent': '',
},
{
  '_id': '2',
  'name': 'B',
  'parent': 'A',
},
{
  '_id': '3',
  'name': 'C',
  'parent': 'B',
},
{
  '_id': '4',
  'name': 'D',
  'parent': 'C',
}
Run Code Online (Sandbox Code Playgroud)
聚合结果:(给定,名称='D')
{
  '_id': '4',
  'name': 'D',
  'ancestors': [{name:'C'}, {name:'B'}, {name:'A'}]
}
Run Code Online (Sandbox Code Playgroud)
Note:我现在无法更改文档结构.这会造成很多问题.我看到许多解决方案建议将模型树结构与祖先数组一起使用.但我现在不能用它.有没有办法用上面的模式使用单个聚合查询来实现它?谢谢
sty*_*ane 15
从MongoDB 3.4开始,我们可以使用聚合框架来完成此任务.
我们管道中的第一个也是最重要的阶段是$graphLookup舞台.$graphLookup允许我们在"父"和"名称"字段上递归匹配.结果,我们得到了每个"名字"的祖先.
管道的下一个阶段是$match我们只选择我们感兴趣的"名称" 的阶段.
最后阶段是$addFields或$project其中我们应用的表达式来使用该"祖先"阵列阶段$map数组运算符.
当然,对于$reverseArray运算符,我们反转数组以获得预期结果.
db.collection.aggregate(
    [ 
        { "$graphLookup": { 
            "from": "collection", 
            "startWith": "$parent", 
            "connectFromField": "parent", 
            "connectToField": "name", 
            "as": "ancestors"
        }}, 
        { "$match": { "name": "D" } }, 
        { "$addFields": { 
            "ancestors": { 
                "$reverseArray": { 
                    "$map": { 
                        "input": "$ancestors", 
                        "as": "t", 
                        "in": { "name": "$$t.name" }
                    } 
                } 
            }
        }}
    ]
)
Run Code Online (Sandbox Code Playgroud)
        |   归档时间:  |  
           
  |  
        
|   查看次数:  |  
           7622 次  |  
        
|   最近记录:  |