首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >MongoDB 递归查询

MongoDB 递归查询

作者头像
用户11690639
发布2026-06-17 21:50:12
发布2026-06-17 21:50:12
00
举报

MongoDB可支持递归查询,需要用到$graphLookup,参见官网示例地址:https://www.mongodb.com/docs/v4.2/reference/operator/aggregation/graphLookup/

现有表的示例数据为:

id

name

pid

parentName

rockBurst

冲击地压

#

microseismicMonitoring

微震监测

rockBurst

冲击地压

realTimeMonitor

微震实时监测

microseismicMonitoring

微震监测

groundSoundMonitoring

地音监测

rockBurst

地音监测

electromagneticRadiationRealTime

地音实时监测

electromagneticRadiation

电磁辐射

返回结果数据

代码语言:javascript
复制
{
"id" : "rockBurst",
"name" : "冲击地压",
"url" : "",
"pid" : "#",
"parentName" : "",
"hierarchy" : [
{
"id" : "groundSoundMonitoring",
"name" : "地音监测",
"url" : "",
"pid" : "rockBurst",
"parentName" : "冲击地压"
},
{
"id" : "groundSoundRealTime",
"name" : "实时监测",
"url" : "/rockBurst/groundSoundMonitoring/realTimeMonitor",
"pid" : "groundSoundMonitoring",
"parentName" : "地音监测"
},
{
"id" : "microseismicMonitoring",
"name" : "微震监测",
"pid" : "rockBurst",
"parentName" : "冲击地压"
},
{
"id" : "realTimeMonitor",
"name" : "实时监测",
"url" : "/rockBurst/index",
"pid" : "microseismicMonitoring",
"parentName" : "微震监测"
}
]
}

Mongo语句说明

代码语言:javascript
复制
{
   $graphLookup: {
      from: <collection>,
      startWith: <expression>,
      connectFromField: <string>,
      connectToField: <string>,
      as: <string>,
      maxDepth: <number>,
      depthField: <string>,
      restrictSearchWithMatch: <document>
   }
}

graphLookup示例:

代码语言:javascript
复制
db.test.test_zl.aggregate([
    {
        $graphLookup: {
            from: "test.test_zl",
            startWith: "$id",
            connectFromField: "id",
            connectToField: "pid",
            as: "hierarchy"
        }
    }])

如果想通过条件查询,并递归查询所有数据,并以记录的形式返回(需求:我想从表中找到根结点是rockBurst的所有二级及三级数据,并复制到别一个表中),这个时候可以结合 match、concatArrays、unwind、replaceRoot等pipeLine操作。

以上相应函数说明

代码语言:javascript
复制
(1){ $replaceRoot: { newRoot: <replacementDocument> } }:将子对象转成根对象
eg:db.students.insertMany([
   {
      "_id" : 1,
      "grades" : [
         { "test": 1, "grade" : 80, "mean" : 75, "std" : 6 },
         { "test": 2, "grade" : 85, "mean" : 90, "std" : 4 },
         { "test": 3, "grade" : 95, "mean" : 85, "std" : 6 }
      ]
   },
   {
      "_id" : 2,
      "grades" : [
         { "test": 1, "grade" : 90, "mean" : 75, "std" : 6 },
         { "test": 2, "grade" : 87, "mean" : 90, "std" : 3 },
         { "test": 3, "grade" : 91, "mean" : 85, "std" : 4 }
      ]
   }
    ])
   db.students.aggregate( [
   { $unwind: "$grades" },
   { $match: { "grades.grade" : { $gte: 90 } } },
   { $replaceRoot: { newRoot: "$grades" } }
    ] )
   result:{ "test" : 3, "grade" : 95, "mean" : 85, "std" : 6 }
          { "test" : 1, "grade" : 90, "mean" : 75, "std" : 6 }
          { "test" : 3, "grade" : 91, "mean" : 85, "std" : 4 }
(2){ $unwind: <field path> }:将数组中的N个对象转成N条对象
eg:db.inventory.insertOne({ "_id" : 1, "item" : "ABC1", sizes: [ "S", "M", "L"] })
   db.inventory.aggregate( [ { $unwind : "$sizes" } ] )
   result:{ "_id" : 1, "item" : "ABC1", "sizes" : "S" }
          { "_id" : 1, "item" : "ABC1", "sizes" : "M" }
          { "_id" : 1, "item" : "ABC1", "sizes" : "L" }

(3){ $concatArrays: [ <array1>, <array2>, ... ] }:多个数组合并在同一数组里
eg:{ $concatArrays: [[ "hello", " "], [ ["world"],"again" ]] }
   result:[ "hello", " ", [ "world" ], "again" ]

本例应用

代码语言:javascript
复制
db.test.test_zl.aggregate([
    {
        $graphLookup: {
            from: "test.test_zl",
            startWith: "$id",
            connectFromField: "id",
            connectToField: "pid",
            as: "hierarchy"
        }
    },
    {
        $match: { id: 'rockBurst' }
    },
    {
        $project: {
            result: {
                $concatArrays: ["$hierarchy", [{ _id: "$_id", id: "$id", name: "$name", url: "", pid: "#", moduleName: "$moduleName", icon: "$icon", order: "$order", parentName: "", checked: "$checked" }]]
            }
        }
    },
    {
        $unwind: "$result"
    },
    {
        $replaceRoot: {
            newRoot: "$result"
        }
    },
    {
        $sort: {
            _id: 1
        }
    }
])

即可返回结果如上表示例数据所示

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2026-06-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档