MongoDB聚合:$graphLookup

这篇具有很好参考价值的文章主要介绍了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" : 3,
   "name" : "Ron",
   "reportsTo" : "Eliot",
   "reportingHierarchy" : [
      { "_id" : 1, "name" : "Dev" },
      { "_id" : 2, "name" : "Eliot", "reportsTo" : "Dev" }
   ]
}
{
   "_id" : 4,
   "name" : "Andrew",
   "reportsTo" : "Eliot",
   "reportingHierarchy" : [
      { "_id" : 1, "name" : "Dev" },
      { "_id" : 2, "name" : "Eliot", "reportsTo" : "Dev" }
   ]
}
{
   "_id" : 5,
   "name" : "Asya",
   "reportsTo" : "Ron",
   "reportingHierarchy" : [
      { "_id" : 1, "name" : "Dev" },
      { "_id" : 2, "name" : "Eliot", "reportsTo" : "Dev" },
      { "_id" : 3, "name" : "Ron", "reportsTo" : "Eliot" }
   ]
}
{
   "_id" : 6,
   "name" : "Dan",
   "reportsTo" : "Andrew",
   "reportingHierarchy" : [
      { "_id" : 1, "name" : "Dev" },
      { "_id" : 2, "name" : "Eliot", "reportsTo" : "Dev" },
      { "_id" : 4, "name" : "Andrew", "reportsTo" : "Eliot" }
   ]
}

下表显示了文件的遍历路径:

{ "_id" : 5, "name" : "Asya", "reportsTo" : "Ron" }:

起始值 文档reportsTo的值
{ ... "reportsTo" : "Ron" }
深度0 { "_id" : 3, "name" : "Ron", "reportsTo" : "Eliot" }
深度1 { "_id" : 2, "name" : "Eliot", "reportsTo" : "Dev" }
深度2 { "_id" : 1, "name" : "Dev" }

输出结果生成的层次结构Asya -> Ron -> Eliot -> Dev

多个集合

$lookup类似,$graphLookup可以跨同一数据库的集合

例如,在同一数据库中分别创建两个集合:

  • airports集合有下列文档:
db.airports.insertMany( [
   { "_id" : 0, "airport" : "JFK", "connects" : [ "BOS", "ORD" ] },
   { "_id" : 1, "airport" : "BOS", "connects" : [ "JFK", "PWM" ] },
   { "_id" : 2, "airport" : "ORD", "connects" : [ "JFK" ] },
   { "_id" : 3, "airport" : "PWM", "connects" : [ "BOS", "LHR" ] },
   { "_id" : 4, "airport" : "LHR", "connects" : [ "PWM" ] }
] )
  • travelers集合有以下文档:
db.travelers.insertMany( [
   { "_id" : 1, "name" : "Dev", "nearestAirport" : "JFK" },
   { "_id" : 2, "name" : "Eliot", "nearestAirport" : "JFK" },
   { "_id" : 3, "name" : "Jeff", "nearestAirport" : "BOS" }
] )

对于travelers集合中的每个文档,下面的聚合操作会查找airports集合中nearestAirport的值,并递归匹配connects字段和airport字段。该操作指定的最大递归深度为2

db.travelers.aggregate( [
   {
      $graphLookup: {
         from: "airports",
         startWith: "$nearestAirport",
         connectFromField: "connects",
         connectToField: "airport",
         maxDepth: 2,
         depthField: "numConnections",
         as: "destinations"
      }
   }
] )

操作返回下面的结果:

{
   "_id" : 1,
   "name" : "Dev",
   "nearestAirport" : "JFK",
   "destinations" : [
      { "_id" : 3,
        "airport" : "PWM",
        "connects" : [ "BOS", "LHR" ],
        "numConnections" : NumberLong(2) },
      { "_id" : 2,
        "airport" : "ORD",
        "connects" : [ "JFK" ],
        "numConnections" : NumberLong(1) },
      { "_id" : 1,
        "airport" : "BOS",
        "connects" : [ "JFK", "PWM" ],
        "numConnections" : NumberLong(1) },
      { "_id" : 0,
        "airport" : "JFK",
        "connects" : [ "BOS", "ORD" ],
        "numConnections" : NumberLong(0) }
   ]
}
{
   "_id" : 2,
   "name" : "Eliot",
   "nearestAirport" : "JFK",
   "destinations" : [
      { "_id" : 3,
        "airport" : "PWM",
        "connects" : [ "BOS", "LHR" ],
        "numConnections" : NumberLong(2) },
      { "_id" : 2,
        "airport" : "ORD",
        "connects" : [ "JFK" ],
        "numConnections" : NumberLong(1) },
      { "_id" : 1,
        "airport" : "BOS",
        "connects" : [ "JFK", "PWM" ],
        "numConnections" : NumberLong(1) },
      { "_id" : 0,
        "airport" : "JFK",
        "connects" : [ "BOS", "ORD" ],
        "numConnections" : NumberLong(0) } ]
}
{
   "_id" : 3,
   "name" : "Jeff",
   "nearestAirport" : "BOS",
   "destinations" : [
      { "_id" : 2,
        "airport" : "ORD",
        "connects" : [ "JFK" ],
        "numConnections" : NumberLong(2) },
      { "_id" : 3,
        "airport" : "PWM",
        "connects" : [ "BOS", "LHR" ],
        "numConnections" : NumberLong(1) },
      { "_id" : 4,
        "airport" : "LHR",
        "connects" : [ "PWM" ],
        "numConnections" : NumberLong(2) },
      { "_id" : 0,
        "airport" : "JFK",
        "connects" : [ "BOS", "ORD" ],
        "numConnections" : NumberLong(1) },
      { "_id" : 1,
        "airport" : "BOS",
        "connects" : [ "JFK", "PWM" ],
        "numConnections" : NumberLong(0) }
   ]
}

下表显示了递归搜索遍历的路径,最大深度为2,开始的airportJFK

开始值 travelers集合中nearestAirport的值
{ ... "nearestAirport" : "JFK" }
深度0 { "_id" : 0, "airport" : "JFK", "connects" : [ "BOS", "ORD" ] }
深度1 { "_id" : 1, "airport" : "BOS", "connects" : [ "JFK", "PWM" ] }, { "_id" : 2, "airport" : "ORD", "connects" : [ "JFK" ] }
深度2 { "_id" : 3, "airport" : "PWM", "connects" : [ "BOS", "LHR" ] }

查询条件

下面的示例使用了一个包含一组文档的集合,文档中包含人名及其朋友和爱好的数组。聚合操作会找到一个特定的人,并遍历她的社交网络,找到爱好为golf的人。

集合people包含了下列文档:

{
  "_id" : 1,
  "name" : "Tanya Jordan",
  "friends" : [ "Shirley Soto", "Terry Hawkins", "Carole Hale" ],
  "hobbies" : [ "tennis", "unicycling", "golf" ]
}
{
  "_id" : 2,
  "name" : "Carole Hale",
  "friends" : [ "Joseph Dennis", "Tanya Jordan", "Terry Hawkins" ],
  "hobbies" : [ "archery", "golf", "woodworking" ]
}
{
  "_id" : 3,
  "name" : "Terry Hawkins",
  "friends" : [ "Tanya Jordan", "Carole Hale", "Angelo Ward" ],
  "hobbies" : [ "knitting", "frisbee" ]
}
{
  "_id" : 4,
  "name" : "Joseph Dennis",
  "friends" : [ "Angelo Ward", "Carole Hale" ],
  "hobbies" : [ "tennis", "golf", "topiary" ]
}
{
  "_id" : 5,
  "name" : "Angelo Ward",
  "friends" : [ "Terry Hawkins", "Shirley Soto", "Joseph Dennis" ],
  "hobbies" : [ "travel", "ceramics", "golf" ]
}
{
   "_id" : 6,
   "name" : "Shirley Soto",
   "friends" : [ "Angelo Ward", "Tanya Jordan", "Carole Hale" ],
   "hobbies" : [ "frisbee", "set theory" ]
 }

下面的聚合操作使用了3个阶段:

  • $match匹配name字段包含字符串"Tanya Jordan"的文档,返回一个输出文档。

  • $graphLookup将输出文档的friends字段与集合中其他文档的name字段连接起来,以遍历Tanya Jordan的社交网络。此阶段使用restrictSearchWithMatch参数只查找爱好数组中包含golf的文档。返回一个输出文档。

  • $project 塑造输出文档。列出的connections who play golf的名字取自输入文档的golfers数组。

db.people.aggregate( [
  { $match: { "name": "Tanya Jordan" } },
  { $graphLookup: {
      from: "people",
      startWith: "$friends",
      connectFromField: "friends",
      connectToField: "name",
      as: "golfers",
      restrictSearchWithMatch: { "hobbies" : "golf" }
    }
  },
  { $project: {
      "name": 1,
      "friends": 1,
      "connections who play golf": "$golfers.name"
    }
  }
] )

操作返回下面的文档:文章来源地址https://www.toymoban.com/news/detail-830203.html

{
   "_id" : 1,
   "name" : "Tanya Jordan",
   "friends" : [
      "Shirley Soto",
      "Terry Hawkins",
      "Carole Hale"
   ],
   "connections who play golf" : [
      "Joseph Dennis",
      "Tanya Jordan",
      "Angelo Ward",
      "Carole Hale"
   ]
}

到了这里,关于MongoDB聚合:$graphLookup的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【MongoDB】--MongoDB聚合Aggregation

    聚合操作组值来自多个文档,可以对分组数据执行各种操作以返回单个结果。聚合操作包含三类: 单一作用聚合、聚合管道、MapReduce 。 单一作用聚合 :提供对常见聚合过程的简单访问,操作都从单个集合聚合文档 聚合管道操作 :将文档在一个管道处理完毕后,把处理的结

    2024年02月14日
    浏览(40)
  • MongoDB——MongoDB删除系统自带的local数据库

    1.1、linux环境进入mongo客户端 输入 mongo 命令,进入命令行客户端 进入admin库,并登录,查看所有数据库 提升用户权限,然后进入local库并删除local库 然后重新进入admin库,把提升的用户权限降回,再次查看所有数据库 由上图可知,local库已被删除。

    2024年02月06日
    浏览(54)
  • [虚幻引擎 MongoDB Client 插件说明] DTMongoDB MongoDB数据库连接插件,UE蓝图可以操作MongoDB数据库增删改查。

    本插件可以在UE里面使用蓝图操作MongoDB数据库, 对数据库进行查询,删除,插入,替换,更新操作。 插件下载地址在文章最后。 Create MongoDB Client - 创建客户端对象 创建一个 MongoDB 客户端对象。 Connect By Url - 连接到数据库 Url :MongoDB的连接地址。 如 mongoDB://account:password@ip:

    2024年02月14日
    浏览(91)
  • MongoDB数据库从入门到精通系列文章之:MongoDB数据库百篇技术文章汇总

    MongoDB数据库系列文章持续更新中: 更多数据库内容请阅读博主数据库专栏,数据库专栏涵盖了Mysql、SQLServer、PostgreSQL、MongoDB、Oracle、Cassandra等数据库 数据库专栏 文章名称 文章链接 数据库安装部署系列之:部署Mongodb5.0.6高可用集群详细步骤 数据库安装部署系列之:部署M

    2024年02月11日
    浏览(54)
  • Mongodb连接数据库

    npm init   npm i mongoose  const mongoose=require(\\\"mongoose\\\") mongoose.connect(\\\"mongodb://127.0.0.1:27017/user\\\") 说明:mongodb是协议,user是数据库,如果没有会自动创建user数据库 。 node 文件名     mongoose.disconnect()

    2024年02月15日
    浏览(59)
  • mongodb数据库操作

    1、启动mongodb 在mongodb启动命令中 --dbpath 指定mongodb的数据存储路径 --logpath 指定mongodb的日志存储路径 2、停止mongodb 第一步先进入mongo命令行模式 第二步,使用use admin 命令进入admin数据库 第三步,执行 db.shutdownServer()命令 停止服务。代码及显示如下:  2 、导出Mongodb数据 mon

    2024年02月09日
    浏览(50)
  • MongoDb数据库

    1.显示所有数据库: show dbs 2.切换到指定数据库,如果没有则自动创建数据库 use databaseName 3.显示当前所在数据库 db 4.删除当前数据库 use 库名 db.dropDatabase() 1.创建集合 db.createCollection(\\\'集合名称\\\') 2.显示当前数据库中所有集合 show colletions  3.删除某个集合 db.xxx.drop(); 4.重命名集

    2024年02月04日
    浏览(54)
  • MongoDB数据库安装

    MongoDB数据的特点: 面相文档存储的分布式数据库 具有很强的扩展性 支持丰富的查询表达式,很接近于关系性数据库 使用类似于json的结构保存数据,可以轻易的查询到文档中内嵌的对象及数组 首先去官网下载安装包 Download MongoDB Community Server | MongoDB 启动MongoDB数据的服务 可

    2024年02月11日
    浏览(57)
  • MongoDB 数据库详细介绍

    MongoDB(来自“Humongous”,意为巨大的)是一个开源、高性能、无模式(NoSQL)、文档导向的分布式数据库。它以其灵活性、可扩展性和强大的查询功能而闻名于世。MongoDB 使用 JSON 格式的文档来存储数据,适用于多种应用场景,包括 Web 应用、移动应用、日志存储、大数据等。

    2024年02月12日
    浏览(65)
  • MongoDB:数据库初步应用

    1.MongoDBCompass连接数据库 连接路径:mongodb://用户名:密码@localhost:27017/ 2.创建数据库(集合) MongoDB中数据库被称为集合.  MongoDBCompass连接后,点击红色框加号创建集合,点击蓝色框加号创建文档(数据表) 文档中的数据结构(相当于表中的列)设计不用管,添加数据的时候,自动创建列和数

    2024年02月12日
    浏览(47)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包