MongoDB 聚合管道的集合关联($lookup)及合并($unionWith)

news/2024/4/27 14:52:36/文章来源:https://blog.csdn.net/m1729339749/article/details/130076038

目前为止,我们已经介绍了一部分聚合管道中的管道参数:

        $match:文档过滤

        $group:文档分组,并介绍了分组中的常用操作:$addToSet,$avg,$sum,$min,$max等。

        $addFields:添加字段,等效于$set

        $unset:移除字段

        $project:字段投影

        $sort:文档排序

        $skip:跳过N条文档

        $limit:获取N条文档

        $sample:随机抽取N条文档

        $unwind:分解文档

如果需要进一步了解可以参考:
MongoDB 聚合管道的文档筛选及分组统计https://blog.csdn.net/m1729339749/article/details/130034658MongoDB 聚合管道的字段投影https://blog.csdn.net/m1729339749/article/details/130055110MongoDB 聚合管道的文档操作https://blog.csdn.net/m1729339749/article/details/130066663本篇我们介绍聚合管道的集合关联及合并操作:

一、准备工作

初始化零食数据

db.snacks.insertMany([{ "_id": 1,  name: "薯片" },{ "_id": 2,  name: "牛肉干" },{ "_id": 3,  name: "可口可乐" },{ "_id": 4,  name: "旺仔牛奶" }
])

初始化零食型号及储量

db.snacksType.insertMany([{ "_id": 1, size: "S", quantity: 10, price: 8, expirationTime: ISODate( "2023-08-08T00:00:00Z" ), "snacks_id": 1 },{ "_id": 2,  size: "L", quantity: 8, price: 12, expirationTime: ISODate( "2023-08-08T00:00:00Z" ), "snacks_id": 1 },{ "_id": 3,  size: "L", quantity: 5, price: 30, expirationTime: ISODate( "2023-10-10T00:00:00Z" ), "snacks_id": 2 },{ "_id": 4,  size: "S", quantity: 10, price: 3, expirationTime: ISODate( "2025-01-06T00:00:00Z" ), "snacks_id": 3 },{ "_id": 5,  size: "L", quantity: 6, price: 10, expirationTime: ISODate( "2025-01-06T00:00:00Z" ), "snacks_id": 3 },{ "_id": 6,  size: "L", quantity: 10, price: 5, expirationTime: ISODate( "2023-08-10T00:00:00Z" ), "snacks_id": 4}
])

二、使用字段关联查询($lookup)

语法:

{$lookup:{from: <collection to join>,localField: <field from the input documents>,foreignField: <field from the documents of the "from" collection>,as: <output array field>}
}

from:指的是关联的集合

localField:指的是当前管道中的字段

foreignField:指的是关联的集合中的字段

as:输出的数组字段;此字段将作为当前管道中的字段,字段的值来源于关联的集合中。

例子:在零食文档中关联上零食对应的所有型号信息

db.snacks.aggregate([{$lookup: {from: "snacksType",localField: "_id",foreignField: "snacks_id",as: "types"}}
])

我们对上面的聚合查询语法进行解释:

使用snacks集合中的字段_id与snacksType集合中的字段snacks_id进行关联查询snacksType集合中的文档,并将查询的结果作为当前管道中types字段的值。

聚合查询的结果如下:

{"_id" : 1,"name" : "薯片","types" : [{"_id" : 1,"size" : "S","quantity" : 10,"price" : 8,"expirationTime" : ISODate("2023-08-08T00:00:00Z"),"snacks_id" : 1},{"_id" : 2,"size" : "L","quantity" : 8,"price" : 12,"expirationTime" : ISODate("2023-08-08T00:00:00Z"),"snacks_id" : 1}]
}
{"_id" : 2,"name" : "牛肉干","types" : [{"_id" : 3,"size" : "L","quantity" : 5,"price" : 30,"expirationTime" : ISODate("2023-10-10T00:00:00Z"),"snacks_id" : 2}]
}
{"_id" : 3,"name" : "可口可乐","types" : [{"_id" : 4,"size" : "S","quantity" : 10,"price" : 3,"expirationTime" : ISODate("2025-01-06T00:00:00Z"),"snacks_id" : 3},{"_id" : 5,"size" : "L","quantity" : 6,"price" : 10,"expirationTime" : ISODate("2025-01-06T00:00:00Z"),"snacks_id" : 3}]
}
{"_id" : 4,"name" : "旺仔牛奶","types" : [{"_id" : 6,"size" : "L","quantity" : 10,"price" : 5,"expirationTime" : ISODate("2023-08-10T00:00:00Z"),"snacks_id" : 4}]
}

可以看出每个零食文档中都增加了一个数组字段types,里面包含了零食对应的型号

三、使用管道关联查询($lookup)

语法:

{$lookup:{from: <joined collection>,let: { <var_1>: <expression>, …, <var_n>: <expression> },pipeline: [ <pipeline to run on joined collection> ],as: <output array field>}
}

from:值的是关联的集合

let:可选,定义变量,这些变量可以在参数pipeline中使用

pipeline:指的是运行在关联的集合上的管道

as:输出的数组字段;此字段将作为当前管道中的字段,字段的值来源于关联的集合执行管道操作后输出的文档。

例子:在零食文档中关联上零食对应的型号、价格、储量、总价值信息

第一步:我们使用管道查询型号集合中的型号、总价值信息

db.snacksType.aggregate([{$project: {"_id": 0,"size": 1,"totalValue": { $multiply: [ "$price", "$quantity" ] }}}
])

执行的结果如下:

{ "size" : "S", "totalValue" : 80 }
{ "size" : "L", "totalValue" : 96 }
{ "size" : "L", "totalValue" : 150 }
{ "size" : "S", "totalValue" : 30 }
{ "size" : "L", "totalValue" : 60 }
{ "size" : "L", "totalValue" : 50 }

 第二步:根据零食关联型号信息

db.snacks.aggregate([{$lookup: {from: "snacksType",let: { "snackId": "$_id" },pipeline: [{ $match: { $expr: { $eq: [ "$snacks_id", "$$snackId" ] } } },{$project: {"_id": 0,"size": 1,"totalValue": { $multiply: [ "$price", "$quantity" ] }}}],as: "types"}}
])

我们对上面的聚合查询语法进行解释:

定义了snackId变量用于存储零食的编号(_id);在集合snacksType对应的管道上使用字段snacks_id对文档进行过滤,然后再进行字段投影。

定义的变量在使用时需要使用 $$ + 变量名;如果使用变量时,需要使用$expr运算符(在$expr运算符内部使用变量)

执行的结果如下:

{"_id" : 1,"name" : "薯片","types" : [{"size" : "S","totalValue" : 80},{"size" : "L","totalValue" : 96}]
}
{"_id" : 2,"name" : "牛肉干","types" : [{"size" : "L","totalValue" : 150}]
}
{"_id" : 3,"name" : "可口可乐","types" : [{"size" : "S","totalValue" : 30},{"size" : "L","totalValue" : 60}]
}
{"_id" : 4,"name" : "旺仔牛奶","types" : [{"size" : "L","totalValue" : 50}]
}

四、合并集合管道

语法:{ $unionWith: { coll: "<collection>", pipeline: [ <stage1>, ... ] } }

合并两个集合的管道

<collection>代表的是集合或者视图

[ <stage1>, ... ] 代表的是对<collection>进行处理的多个阶段组成的管道

例子:合并零食与型号集合中的文档

db.snacks.aggregate([{$project: { "name": 1, "_id": 0 }},{$unionWith: {coll: "snacksType",pipeline: [{ $project: { "size": "1", "_id": 0 } } ]}}
])

我们对聚合查询进行一下解释:

(1) 使用$project 对snacks集合中的文档进行投影,投影后只保留了name字段

(2) 使用$project 对snacksType集合中的文档进行投影,投影后只保留了size字段

(3) 使用$unionWith 对两个集合的管道进行合并

执行的结果如下:

{ "name" : "薯片" }
{ "name" : "牛肉干" }
{ "name" : "可口可乐" }
{ "name" : "旺仔牛奶" }
{ "size" : "S" }
{ "size" : "L" }
{ "size" : "L" }
{ "size" : "S" }
{ "size" : "L" }
{ "size" : "L" }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_286475.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

可用的rtsp ,rtmp地址以及使用VLC和ffmpeg 播放视频流

可用的 rtmp地址: rtmp://ns8.indexforce.com/home/mystream 可用的 rtsp地址: rtsp://wowzaec2demo.streamlock.net/vod/mp4:BigBuckBunny_115k.mp4 可搭配VLC播放器使用&#xff0c;以及虚幻4 流媒体使用&#xff0c;实现直播效果 1.使用VLC 播放&#xff1a;https://www.vi…

某某客户的一次勒索病毒应急响应

Lockbit勒索病毒应急响应背景1、应急处理排查2、勒索病毒来源分析3、勒索病毒分析4、勒索病毒解密5、主机分析分析6、后续安全加固和改进措施结论背景 美好的周六刚开始&#xff0c;眼睛一睁&#xff0c;领导就发消息&#xff0c;说某客户中了勒索病毒&#xff0c;特别着急&am…

2023年第三届智能机器人与系统国际会议(ISoIRS 2023) | IEEE-CPS独立出版

2023年第三届智能机器人与系统国际会议(ISoIRS 2023) | IEEE-CPS独立出版 会议简介 Brief Introduction 2023年第三届智能机器人与系统国际会议(ISoIRS 2023) 会议时间&#xff1a;2023年5月26日-28日 召开地点&#xff1a;中国长沙 大会官网&#xff1a;www.isoirs.org ISoIRS…

项目打包记录提交id

某天上午正在摸鱼的小邓&#xff0c;突然被领导拉倒一个2年前项目的现场问题沟通群&#xff0c;说是现场数据无法入库&#xff0c;需要排查&#xff0c;奈何不知道版本&#xff0c;无奈的小邓值得用时间记录一个点一个点的从gitlab中查找&#xff0c;为了防止后续提供到现场的版…

基于DSP+FPGA的机载雷达伺服控制系统的硬件设计与开发(一)总体设计

2.1 功能要求及性能指标 2.1.1 功能要求 &#xff08;1&#xff09;具备方位和俯仰两轴运动的能力&#xff1b; &#xff08;2&#xff09;方位轴可实现预置、周扫和扇扫功能&#xff1b; &#xff08;3&#xff09;俯仰轴可实现预置功能。 2.1.2 性能指标 &#xff08;1&#…

江南爱窗帘十大品牌,怎么合理的搭配窗帘配色

窗帘行业圈&#xff1a;窗帘行业内部交流圈&#xff0c;窗帘从业者的交流内部圈。 当阳光照进房间的那一刻&#xff0c; 光线给空间带来了无限的可能。 窗边的帘帐既是美丽的风景 又是可爱的魔术师。 在光影变幻的时空里 让你的生活布满温馨和奇幻。 1.窗帘材质怎么选 窗帘的材…

Voting_Averaging算法预测银行客户流失率

Voting_Averaging算法预测银行客户流失率 描述 为了防止银行的客户流失&#xff0c;通过数据分析&#xff0c;识别并可视化哪些因素导致了客户流失&#xff0c;并通过建立一个预测模型&#xff0c;识别客户是否会流失&#xff0c;流失的概率有多大。以便银行的客户服务部门更…

Qt Quick - 分隔器综述

Qt Quick - 分隔器综述一、概述二、MenuSeparator 控件1. 用法&#xff1a;三、ToolSeparator 控件1. 用法一、概述 Qt Quick Controls 提供了多种分隔符&#xff0c;其实就是分割一下MenuBar和ToolBar里面的内容。 控件功能MenuSeparator将菜单中的一组项目与相邻项目分开To…

高效部署Redis Sentinel模式(哨兵模式),手把手教学

Redis Sentinel模式部署前言一、服务器部署同版本的redis1、换软件源在yum拉取包的时候启用remi源二、修改配置文件1.修改/etc/redis.conf2.配置/etc/redis/sentinel.conf三、启动redis服务1、启动服务2、连接redis3、检查redis前言 这里就不过多的解释高可用的好处了&#xf…

一文吃透Http协议

Http 协议 1. 初始 Http Http 协议 , 是应用层最为广泛使用的协议 , Http 就是浏览器和服务器之间的桥梁. Http 是基于 TCP 协议实现的 , 通常我们输入搜索框中的网址 (URL) , 浏览器就会根据这个 URL 构造出一个 Http 请求 , 发送给服务器. 服务器就会返回一个 Http 响应(包…

计组2.4——加法器的设计

计组&#xff1a;2.4算术逻辑单元异或门实现奇偶校验的原理串行加法器&&并行加法器并行加法器的优化算术逻辑单元 控制信号&#xff1a; 当M0时表示算术运算 当M1时表示逻辑运算 S0~ S3表示做什么运算&#xff0c;因此ALU可以表示16种算数运算和16种逻辑运算 Ai,Bi代表…

JVM 垃圾收集器详解

一、垃圾收集器 如果说收集算法是内存回收的方法论&#xff0c;那垃圾收集器就是内存回收的实践者。《Java虚拟机规范》中对垃圾收集器应该如何实现并没有做出任何规定&#xff0c;因此不同的厂商、不同版本的虚拟机所包含的垃圾收集器都可能会有很大差别&#xff0c;不同的虚…

Java中Cookie的属性介绍

Name和Value Name和Value是一个键值对。 Name是Cookie的名称&#xff0c;Cookie一旦创建&#xff0c;名称便不可更改&#xff0c;一般名称不区分大小写&#xff1b; Value是该名称对应的Cookie的值&#xff0c;如果值为Unicode字符&#xff0c;需要为字符编码。 如果值为二进制…

优思学院|质量大师的那些名言(一)【质量是免费的】

名言是一种短小精悍、言简意赅的语言表达方式&#xff0c;它们通常包含着深刻的哲理和智慧&#xff0c;可以为我们提供指导和启示。 优思学院会在这个《质量大师的那些名言》系列中让大家透过那些名言&#xff0c;用最简单、直接&#xff0c;和深刻的方法来学习质量和六西格玛…

商城系统开发方案分析

互联网的不断发展&#xff0c;电商行业已经成为了当前最重要的商业形式之一。商城系统的开发也因此而备受关注。商城系统的开发是针对B2C、B2B2C等多种商业模式&#xff0c;如用户熟知的SHOP、商派等一系列商城系统&#xff0c;将商品和服务进行在线销售的一个综合性平台。那么…

字节面试体验值拉满~

今天分享一位读者春招的字节二面面经&#xff0c;岗位是后端开发。 一个编程语言都没问&#xff0c;都是问网络项目mysqlredis。 问题记录 使用消息中间件降低消息持久化的压力是怎么做的&#xff0c;为什么可以降低&#xff1f; 读者答&#xff1a;在突发大量消息的情况下…

云桌面初体验 之 爱上无影云桌面

什么是无影云桌面 无影云桌面 (Elastic Desktop Service&#xff09;&#xff0c;一台长在云上的“超级电脑”&#xff0c;是基于云计算和虚拟化技术的云上桌面服务。 支持桌面环境的快速创建、部署、统一管控与运维&#xff1b;在便捷性、弹性、安全、高性能等方面&#xff…

polygraphy深度学习模型调试器使用教程

深度学习系列文章目录 文章目录深度学习系列文章目录Polygraphy介绍一、安装源码安装&#xff1a;简单安装安装依赖二、简单使用三、使用教程2 、polygtaphy使用示例Polygraphy介绍 Polygraphy在我进行模型精度检测和模型推理速度的过程中都有用到&#xff0c;因此在这做一个简…

腾讯云GPU服务器NVIDIA P40 GPU、P4、T4和GPU自由卡详解

腾讯云GPU云服务器&#xff0c;GPU云服务器实例可选GN8机型、GN6S机型、GN7机型等规格&#xff0c;搭载 NVIDIA P40 GPU&#xff0c;最长可3年&#xff0c;云服务器吧来详细说下腾讯云GPU云服务器&#xff1a; 目录 腾讯云GPU云服务器 腾讯云GPU自由卡 腾讯云GPU云服务器 腾…

归并排序(递归+非递归)

目录一、什么是归并排序&#xff1f;二、归并排序&#xff08;递归&#xff09;三、归并排序&#xff08;非递归&#xff09;一、什么是归并排序&#xff1f; 归并排序&#xff0c;是创建在归并操作上的一种有效的排序算法。算法是采用分治法&#xff08;Divide and Conquer&a…