MongoDB聚合:$graphLookup

$graphLookup聚合阶段在一个集合中执行递归搜索,可以使用选项来控制递归搜索的深度和条件。

$graphLookup搜索过程总结如下:

  1. 输入文档进入$graphLookup聚合阶段。
  2. $graphLookup的搜索目标是from参数指定的集合(搜索参数的完整列表见下文)。
  3. 对于每个输入文档,搜索都从startWith指定的值开始。
  4. graphLookup使用startWith的值匹配由from指定的集合和connectToField指定的字段的值。
  5. 对于每个匹配文档,$graphLookupconnectFromField的值来检查每个from参数指定的集合下的connectToField参数指定的字段的值,然后将匹配上的from集合的文档放到由as参数指定的数组中。
    然后该步骤继续递归直到没有匹配的文档或操作达到由maxDepth参数指定的递归深度。然后$graphLookup把数组字段添加到输入文档。在完成所有的文档搜索后返回结果。

语法

{
   
   
   $graphLookup: {
   
   
      from: <collection>,
      startWith: <expression>,
      connectFromField: <string>,
      connectToField: <string>,
      as: <string>,
      maxDepth: <number>,
      depthField: <string>,
      restrictSearchWithMatch: <document>
   }
}

参数字段解释:

字段 描述
from $graphLookup操作搜索的目标集合,递归匹配connectFromFieldconnnectToField字段的值,from指定的集合必须与当前集合在同一个数据库,并且不可以是同一个集合
startWith 可选,表达式,connectFromField字段进行递归搜索的起始值。startWith的值也可以是数组,其每个值都会被遍历处理
connectFromField 指定一个字段名,其值用于递归搜索匹配。与集合中其他文档connectToField相对应,如果其值是数组,则会在遍历时单独处理每个元素
connectToField 其他文档中的字段名称,用于匹配connectFromField参数指定的字段值
as 添加到每个输出文档中的数组字段名称。包含在$graphLook阶段遍历的所有文档(注意,数组元素的顺序不保证)
maxDepth 可选,正整数,指定最大的递归深度
depthField 可选,要添加到搜索路径中每个遍历文档的字段名称。该字段的值是文档的递归深度,长整数。递归深度值从零开始,因此第一次查找对应的深度为零
restrictSearchWithMatch 可选,文档类型。为递归搜索指定额外的条件,其语法与查询过滤语法相同。可以在过滤条件中使用所有的聚合表达式,如:{ lastName: { $ne: "$lastName" } },该表达式无法在该上下文中查找lastName值与输入文档的lastName值不同的文档,因为“$lastName”将充当字符串文本,而不是字段路径

使用

分片集合

从MongoDB 5.1开始,可以在from参数中指定分片集合,但不能在事务中使用分片集合。

最大递归深度

maxDepth字段设置为0相当于一个非递归的$graphLookup搜索阶段

内存

$graphLookup阶段有100M内存的限制,如果想突破这个限制,可以为聚合指定allowDiskUse: true,该设置也会影响到$graphLookup中使用的其他聚合阶段。

视图和集合

如果执行涉及多个视图的聚合,如使用$lookup$graphLookup,视图必须有相同的集合。

举例

单个集合

employees集合有下面的文档:

{
   
    "_id" : 1, "name" : "Dev" }
{
   
    "_id" : 2, "name" : "Eliot", "reportsTo" : "Dev" }
{
   
    "_id" : 3, "name" : "Ron", "reportsTo" : "Eliot" }
{
   
    "_id" : 4, "name" : "Andrew", "reportsTo" : "Eliot" }
{
   
    "_id" : 5, "name" : "Asya", "reportsTo" : "Ron" }
{
   
    "_id" : 6, "name" : "Dan", "reportsTo" : "Andrew" }

下面的$graphLookup递归匹配employees集合中reportsToname字段,返回每个人的报告层次结构:

db.employees.aggregate( [
   {
   
   
      $graphLookup: {
   
   
         from: "employees",
         startWith: "$reportsTo",
         connectFromField: "reportsTo",
         connectToField: "name",
         as: "reportingHierarchy"
      }
   }
] )

操作返回下面的结果:

{
   
   
   "_id" : 1,
   "name" : "Dev",
   "reportingHierarchy" : [ ]
}
{
   
   
   "_id" : 2,
   "name" : "Eliot",
   "reportsTo" : "Dev",
   "reportingHierarchy" : [
      {
   
    "_id" : 1, "name" : "Dev" }
   ]
}
{
   
   
   "_id" : 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

原子星

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值