二丫讲梵 二丫讲梵
首页
  • 最佳实践
  • 迎刃而解
  • Nginx
  • Php
  • Zabbix
  • AWS
  • Prometheus
  • Grafana
  • CentOS
  • Systemd
  • Docker
  • Rancher
  • Ansible
  • Ldap
  • Gitlab
  • GitHub
  • Etcd
  • Consul
  • RabbitMQ
  • Kafka
  • MySql
  • MongoDB
  • OpenVPN
  • KVM
  • VMware
  • Other
  • ELK
  • K8S
  • LLM
  • Nexus
  • Jenkins
  • 随写编年
  • 家人物语
  • 追忆青春
  • 父亲的朋友圈
  • 电影音乐
  • 效率工具
  • 博客相关
  • Shell
  • 前端实践
  • Vue学习笔记
  • Golang学习笔记
  • Golang编程技巧
  • 学习周刊
  • Obsidian插件周刊
关于
友链
  • 本站索引

    • 分类
    • 标签
    • 归档
  • 本站页面

    • 导航
    • 打赏
  • 我的工具

    • 备忘录清单 (opens new window)
    • json2go (opens new window)
    • gopher (opens new window)
    • 微信MD编辑 (opens new window)
    • 国内镜像 (opens new window)
    • 出口IP查询 (opens new window)
    • 代码高亮工具 (opens new window)
  • 外站页面

    • 开往 (opens new window)
    • ldapdoc (opens new window)
    • HowToStartOpenSource (opens new window)
    • vdoing-template (opens new window)
GitHub (opens new window)

二丫讲梵

行者常至,为者常成
首页
  • 最佳实践
  • 迎刃而解
  • Nginx
  • Php
  • Zabbix
  • AWS
  • Prometheus
  • Grafana
  • CentOS
  • Systemd
  • Docker
  • Rancher
  • Ansible
  • Ldap
  • Gitlab
  • GitHub
  • Etcd
  • Consul
  • RabbitMQ
  • Kafka
  • MySql
  • MongoDB
  • OpenVPN
  • KVM
  • VMware
  • Other
  • ELK
  • K8S
  • LLM
  • Nexus
  • Jenkins
  • 随写编年
  • 家人物语
  • 追忆青春
  • 父亲的朋友圈
  • 电影音乐
  • 效率工具
  • 博客相关
  • Shell
  • 前端实践
  • Vue学习笔记
  • Golang学习笔记
  • Golang编程技巧
  • 学习周刊
  • Obsidian插件周刊
关于
友链
  • 本站索引

    • 分类
    • 标签
    • 归档
  • 本站页面

    • 导航
    • 打赏
  • 我的工具

    • 备忘录清单 (opens new window)
    • json2go (opens new window)
    • gopher (opens new window)
    • 微信MD编辑 (opens new window)
    • 国内镜像 (opens new window)
    • 出口IP查询 (opens new window)
    • 代码高亮工具 (opens new window)
  • 外站页面

    • 开往 (opens new window)
    • ldapdoc (opens new window)
    • HowToStartOpenSource (opens new window)
    • vdoing-template (opens new window)
GitHub (opens new window)
  • MongoDB关联查询的学习以及实践

    • 过滤数据
    • 运维观止
    • MongoDB
    二丫讲梵
    2022-03-16
    目录

    MongoDB关联查询的学习以及实践

    文章发布较早,内容可能过时,阅读注意甄别。

    MongoDB 的关联查询主要依赖$lookup 方法来进行,下边通过实际例子先来了解感受一下关联查询的场景以及用法。

    还是以分组,和成员来举例。

    首先创建两个分组:

    db.group.insert([
       { "name" : "运维组", "identify": "yunweizu"},
       { "name" : "客服组", "identify": "kefuzu"}
    ])
    
    1
    2
    3
    4

    表示在 group 这张表里添加两条记录。

    然后创建几个用户:

    db.user.insert([
       { "name" : "小A", "identify": "aaa","groupIdentify":"yunweizu"},
       { "name" : "小B", "identify": "bbb","groupIdentify":"yunweizu"},
       { "name" : "小C", "identify": "ccc","groupIdentify":"yunweizu"},
       { "name" : "小D", "identify": "ddd","groupIdentify":"kefuzu"},
       { "name" : "小E", "identify": "eee","groupIdentify":"kefuzu"},
       { "name" : "小F", "identify": "fff","groupIdentify":"kefuzu"},
    ])
    
    1
    2
    3
    4
    5
    6
    7
    8

    查询每个组以及组内的用户:

    db.group.aggregate([
        {
            $lookup:
            {
                from:"user",
                localField:"identify",
                foreignField:"groupIdentify",
                as:"output"
            }
        }
    ])
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    • aggregate():在 MongoDB 中是聚合的方法。参考 (opens new window)
    • $lookup:表示多表关联。
      • from:同一个数据库下等待被 Join 的集合。
      • localField:源集合中的 match 值,如果输入的集合中,某文档没有  localField 这个 Key(Field),在处理的过程中,会默认为此文档含有 localField:null 的键值对。
      • foreignField:待 Join 的集合的 match 值,如果待 Join 的集合中,文档没有 foreignField 值,在处理的过程中,会默认为此文档含有 foreignField:null 的键值对。
      • as:为输出文档的新增值命名。如果输入的集合中已存在该值,则会覆盖掉。

    展示数据如下:

    /* 1 */
    {
        "_id" : ObjectId("61f0f6c2c8d32bc297dbecd2"),
        "name" : "运维组",
        "identify" : "yunweizu",
        "output" : [
            {
                "_id" : ObjectId("61f0f6d6c8d32bc297dbecd4"),
                "name" : "小A",
                "identify" : "aaa",
                "groupIdentify" : "yunweizu"
            },
            {
                "_id" : ObjectId("61f0f6d6c8d32bc297dbecd5"),
                "name" : "小B",
                "identify" : "bbb",
                "groupIdentify" : "yunweizu"
            },
            {
                "_id" : ObjectId("61f0f6d6c8d32bc297dbecd6"),
                "name" : "小C",
                "identify" : "ccc",
                "groupIdentify" : "yunweizu"
            }
        ]
    }
    
    /* 2 */
    {
        "_id" : ObjectId("61f0f6c2c8d32bc297dbecd3"),
        "name" : "客服组",
        "identify" : "kefuzu",
        "output" : [
            {
                "_id" : ObjectId("61f0f6d6c8d32bc297dbecd7"),
                "name" : "小D",
                "identify" : "ddd",
                "groupIdentify" : "kefuzu"
            },
            {
                "_id" : ObjectId("61f0f6d6c8d32bc297dbecd8"),
                "name" : "小E",
                "identify" : "eee",
                "groupIdentify" : "kefuzu"
            },
            {
                "_id" : ObjectId("61f0f6d6c8d32bc297dbecd9"),
                "name" : "小F",
                "identify" : "fff",
                "groupIdentify" : "kefuzu"
            }
        ]
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53

    从结果可以做下分析: 从 user 表中获取所有文档,拿到的文档会使用groupIdentify字段的值遍历被 Join 的 group 表,如果匹配到,就会把 user 表整体内嵌到新生成的 output 数组下。

    # 过滤数据

    如果想要过滤条件,则使用$match进行过滤,比如我只想查看运维组的人员:

    db.group.aggregate([
        {$match:{"identify":"yunweizu"}},
        {
            $lookup:
            {
                from:"user",
                localField:"identify",
                foreignField:"groupIdentify",
                as:"output"
            }
        }
    ])
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12

    输出结果为:

    /* 1 */
    {
        "_id" : ObjectId("61f0f6c2c8d32bc297dbecd2"),
        "name" : "运维组",
        "identify" : "yunweizu",
        "output" : [
            {
                "_id" : ObjectId("61f0f6d6c8d32bc297dbecd4"),
                "name" : "小A",
                "identify" : "aaa",
                "groupIdentify" : "yunweizu"
            },
            {
                "_id" : ObjectId("61f0f6d6c8d32bc297dbecd5"),
                "name" : "小B",
                "identify" : "bbb",
                "groupIdentify" : "yunweizu"
            },
            {
                "_id" : ObjectId("61f0f6d6c8d32bc297dbecd6"),
                "name" : "小C",
                "identify" : "ccc",
                "groupIdentify" : "yunweizu"
            }
        ]
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26

    这里是为了了解 MongoDB 的关联查询,而做的一些实验,实际生产当中的查询,其实很少会直接这样用关联查询,毕竟 MongoDB 是一个非关系型数据库,更多时候是查询之后,通过程序在内存中判断聚合。

    • 参考
      • 实记 | MongoDB 多表连接查询 (opens new window)
    微信 支付宝
    #MongoDB
    上次更新: 2024/06/13, 22:13:45
    最近更新
    01
    记录二五年五一之短暂回归家庭
    05-09
    02
    学习周刊-总第210期-2025年第19周
    05-09
    03
    学习周刊-总第209期-2025年第18周
    05-03
    更多文章>
    Theme by Vdoing | Copyright © 2017-2025 | 点击查看十年之约 | 浙ICP备18057030号
    • 跟随系统
    • 浅色模式
    • 深色模式
    • 阅读模式