08、MongoDB -- MongoDB 的 集合关联($lookup 和 DBRef 实现集合关联)
目录
- MongoDB 的 集合关联
- 演示前提:
- 登录单机模式的 mongodb 服务器命令
- 登录【test】数据库的 mongodb 客户端命令
- 登录【admin】数据库的 mongodb 客户端命令
- SQL 术语 与 Mongodb 的对应关系
- 使用 $lookup 实现集合关联
- 语法格式
- 添加测试数据
- 1、查询出订单数量大于6,及其对应的商品:
- 1-1:查询出订单中,【amount】数量大于6的订单
- 1-2:查询出订单中,【amount】数量大于 6 的订单,及其对应的商品
- 查询命令
- 命令解释
- 查询结果
- 2、查询出价格为 30 的商品所关联的全部订单
- 2-1:查询【item】集合中价格为 30 的商品:
- 2-2:查询出价格为 30 的商品所关联的全部订单
- 查询命令
- 命令解释
- 查询结果
- 使用 DBRef 实现集合关联
- 语法格式
- 添加测试数据
- 1、查询标题为 “标题2" 的 comment 及对应的商品
- 1-1:查询标题为 “标题2" 的 comment
- 查询命令
- 查询结果
- 1-2:查询标题为 “标题2" 的 comment 文档 及 对应的商品
- 查询返回的文档只有一条数据:
- 查询命令:
- 查询结果
- 查询返回的文档有多条数据:
- 查询命令
- 查询结果
MongoDB 的 集合关联
演示前提:
登录单机模式的 mongodb 服务器命令
mongod.exe --config "E:\install\mongodb\mongodb-4.2.25\mongod.conf"

登录【test】数据库的 mongodb 客户端命令
mongo mongodb://192.168.0.107:27017/test -u LJHAAA -p 123456

登录【admin】数据库的 mongodb 客户端命令
mongo mongodb://192.168.0.107:27017/admin -u admin -p 123456

SQL 术语 与 Mongodb 的对应关系

使用 $lookup 实现集合关联
语法格式
在聚集运算使用如下文档:
{$lookup:{from: 指定要连接的集合localField: 指定本集合中文档的主键字段foreignField: 指定要连接的集合中的外键字段as: 指定被连接对象的属性名}}
localField 和 foreignField 指定两个集合之间的关联条件
添加测试数据
原本的 item 集合有这些数据

价格为 30 的【键盘】,和 订单 1、2、3相关联;
价格为 60 的【鼠标】,和 订单 4、5 相关联;
db.order.insert([{item_id: ObjectId("65e6cb5e055c945aa89b8575"), name: "订单1", amount: 3},{item_id: ObjectId("65e6cb5e055c945aa89b8575"), name: "订单2", amount: 5},{item_id: ObjectId("65e6cb5e055c945aa89b8575"), name: "订单3", amount: 8},{item_id: ObjectId("65e6cb5e055c945aa89b8578"), name: "订单4", amount: 4},{item_id: ObjectId("65e6cb5e055c945aa89b8578"), name: "订单5", amount: 7}
])
如图:生成一个【order】的订单集合,相当于sql的订单表。

1、查询出订单数量大于6,及其对应的商品:
1-1:查询出订单中,【amount】数量大于6的订单

1-2:查询出订单中,【amount】数量大于 6 的订单,及其对应的商品
查询命令
db.order.aggregate([{$match: {amount: {$gt: 6}}},{ $lookup: {from: "item",localField: "item_id",foreignField: "_id",as: "item_detail"}}
])
命令解释
db.order.aggregate([ //aggregate 表示对 MongoDB 中的 order 集合执行聚集运算{$match: {amount: {$gt: 6}}}, //这是聚合管道中的第一个阶段,相当于where 条件:查询 amount > 6 的订单 { $lookup: // 这是聚合管道中的第二个阶段,使用 $lookup 操作符来执行关联查询{from: "item", //指定要连接的集合,这里是连接【item】这个集合(表)localField: "item_id", // 指定当前集合(order)中用于关联的字段为 item_idforeignField: "_id", //指定要关联的集合(item)中用于关联的字段为 _idas: "item_detail" //指定将关联查询的结果存储到名为 item_detail 的字段中}}
])
相当于 SQL 中的 join 查询:
select * from order o
join item i on o.item_id = i . _id
where o.amout > 6;

查询结果

2、查询出价格为 30 的商品所关联的全部订单
2-1:查询【item】集合中价格为 30 的商品:
db.item.aggregate([{$match:{price:30}}
])

2-2:查询出价格为 30 的商品所关联的全部订单
查询命令
db.item.aggregate([{$match: {price: 30}},{$lookup: {from: "order",localField: "_id",foreignField: "item_id",as: "order_array"}}
])
命令解释
db.item.aggregate([{$match: {price: 30}}, //这是聚合管道中的第一个阶段,用于筛选出【item】集合中 price 等于 30 的 数据{$lookup: { //这是聚合管道中的第二个阶段,使用 $lookup 操作符来执行关联查询from: "order", //指定要关联查询的集合为 orderlocalField: "_id", //指定当前集合(item)中用于关联的字段为 _idforeignField: "item_id", //指定要关联的集合(order)中用于关联的字段为 item_idas: "order_array" //指定将关联查询的结果存储到名为 order_array 的字段中}}
])
查询结果

使用 DBRef 实现集合关联
语法格式
DBRef 尽可能地模拟了SQL数据库中外键——指定要引用哪个表的哪个列。
插入文档时使用 DBRef 引用其他文档,DBRef 的完整形式:
{ $ref : 被引用的集合名 , $id : 被引用的文档主键< value > , $db : 被引用的数据库 }
如果被引用的集合在同一个数据库中,$db 可以省略。
通过 DBRef 的 fetch() 方法即可抓取关联文档。
添加测试数据
db.comment.insert([{item: {$ref: "item", $id: ObjectId("65e6cb5e055c945aa89b8575")}, title: "标题1", body: "评论内容1"},{item: {$ref: "item", $id: ObjectId("65e6cb5e055c945aa89b8575")}, title: "标题2", body: "评论内容2"},{item: {$ref: "item", $id: ObjectId("65e6cb5e055c945aa89b8575")}, title: "标题3", body: "评论内容3"},{item: {$ref: "item", $id: ObjectId("65e6cb5e055c945aa89b8575")}, title: "标题4", body: "评论内容4"},{item: {$ref: "item", $id: ObjectId("65e6cb5e055c945aa89b8575")}, title: "标题5", body: "评论内容5"}
])
item: 这是一个嵌套的字段,包含了一个引用到 item 集合中某个文档的信息。
$ref: “item”: 指定了引用的集合为 item。
$id: ObjectId(“65e6cb5e055c945aa89b8575”): 指定了引用的文档的 ObjectId。
如图:引用了 item 集合中的 id 为 【65e6cb5e055c945aa89b8575】 的文档

测试数据:

1、查询标题为 “标题2" 的 comment 及对应的商品
1-1:查询标题为 “标题2" 的 comment
查询命令
db.comment.findOne({title: "标题2"})
查询结果

1-2:查询标题为 “标题2" 的 comment 文档 及 对应的商品
【备注】如果你已经用了 DBRef 来记录关联,程序可以非常方便处理关联,压根不需要使用 $lookup
查询返回的文档只有一条数据:
查询命令:
db.comment.findOne({title: "标题2"}).item.fetch()
查询结果
在 studio 3t 这个图形界面工具查询就出错。

修改成这样:
db.comment.findOne({title: "标题2"}, {item: 1})

在命令行窗口查询就可以


查询返回的文档有多条数据:
如果查询的包含了多个文档,且要通过DBRef获取关联文档时,
由于 find() 方法返回的是 DBCursor,因此需要先遍历 DBCursor,然后在通过查询文档的关联属性来获取关联的文档。
DBCursor 有一个 forEach 方法,该方法需要传入一个 JS 的 function( c ) {c就代表了正则遍历的文档},
通过该函数可对DbCursor中多个文档进行遍历。
查询命令
db.comment.find({title: "标题2"}).forEach(function(c){print(JSON.stringify(c) + JSON.stringify(c.item.fetch()));
})
查询结果

相关文章:
08、MongoDB -- MongoDB 的 集合关联($lookup 和 DBRef 实现集合关联)
目录 MongoDB 的 集合关联演示前提:登录单机模式的 mongodb 服务器命令登录【test】数据库的 mongodb 客户端命令登录【admin】数据库的 mongodb 客户端命令 SQL 术语 与 Mongodb 的对应关系使用 $lookup 实现集合关联语法格式添加测试数据1、查询出订单数量大于6&a…...
前方高能,又一波Smartbi签约喜报来袭
近期,交通银行、厦门国际银行、中原农业保险、江苏中天科技等多家知名企业签约Smartbi,携手Smartbi实现数据驱动业务新增长。 Smartbi数10年专注于商业智能BI与大数据分析软件与服务,为各行各业提供提供一站式商业智能平台(PaaS&a…...
蓝桥杯倒计时 41天 - 二分答案-最大通过数-妮妮的月饼工厂
最大通过数 思路:假设左边能通过 x 关,右边能通过 y 关,x∈[0,n],通过二分,在前缀和中枚举右边通过的关卡数,保存 xy 的最大值。 #include<bits/stdc.h> using namespace std; typedef long long ll…...
【JavaSE】泛型
系列文章目录 提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 系列文章目录前言一、pandas是什么?二、使用步骤 1.引入库2.读入数据总结 前言 学习泛型之前请大家先详细地了解一下,关于Java…...
APS(高级计划与调度系统)难度超高,ERP在它面前就是弟弟。
一、APS定义和功能模块 APS系统是Advanced Planning and Scheduling System(高级计划与调度系统)的缩写。它是一种计划和调度管理软件系统,旨在帮助企业优化生产计划和资源调度,提高生产效率和响应能力。 APS系统利用先进的算法和…...
ArmV8架构
Armv8/armv9架构入门指南 — Armv8/armv9架构入门指南 v1.0 documentation 上面只是给了一个比较好的参考文档 其他内容待补充...
[论文笔记] Open-sora 2、视频数据集介绍 MSR-VTT
MSR-VTT COVE - Computer Vision Exchange 论文参考:https://www.microsoft.com/en-us/research/wp-content/uploads/2016/06/cvpr16.msr-vtt.tmei_-1.pdf 用于视频理解的大规模视频基准,特别是将视频翻译为文本的新兴任务。这是通过从商业视频搜索引擎收集 257 个热门查询…...
【Windows 常用工具系列 14 -- windows 网络驱动映射】
文章目录 windows 网络驱动映射 windows 网络驱动映射 映射网络驱动器的意思是将局域网中的某个目录映射成本地驱动器号。 在windows上将服务器目录映射到本地盘: 进入到服务器执行下面命令既可以看到对应的 IP地址: 将对应的IP地址填入上图中。 映…...
Java中使用Jsoup实现网页内容爬取与Html内容解析并使用EasyExcel实现导出为Excel文件
场景 Pythont通过request以及BeautifulSoup爬取几千条情话: Pythont通过request以及BeautifulSoup爬取几千条情话_爬取情话-CSDN博客 Node-RED中使用html节点爬取HTML网页资料之爬取Node-RED的最新版本: Node-RED中使用html节点爬取HTML网页资料之爬…...
闫震海:腾讯音乐空间音频技术的发展和应用 | 演讲嘉宾公布
一、3D 音频 3D 音频分论坛将于3月27日同期举办! 3D音频技术不仅能够提供更加真实、沉浸的虚拟世界体验,跨越时空的限制,探索未知的世界。同时,提供更加丰富、立体的情感表达和交流方式,让人类能够更加深入地理解彼此&…...
Java基础 - 6 - 面向对象(二)
Java基础 - 6 - 面向对象(一)-CSDN博客 二. 面向对象高级 2.1 static static叫做静态,可以修饰成员变量、成员方法 2.1.1 static修饰成员变量 成员变量按照有无static修饰,分为两种:类变量、实例变量(对象…...
SpringCloud-MQ消息队列
一、消息队列介绍 MQ (MessageQueue) ,中文是消息队列,字面来看就是存放消息的队列。也就是事件驱动架构中的Broker。消息队列是一种基于生产者-消费者模型的通信方式,通过在消息队列中存放和传递消息,实现了不同组件、服务或系统…...
代码随想录算法训练营第三十八天|509. 斐波那契数、70. 爬楼梯、746. 使用最小花费爬楼梯
509. 斐波那契数 刷题https://leetcode.cn/problems/fibonacci-number/description/文章讲解https://programmercarl.com/0509.%E6%96%90%E6%B3%A2%E9%82%A3%E5%A5%91%E6%95%B0.html#%E7%AE%97%E6%B3%95%E5%85%AC%E5%BC%80%E8%AF%BE视频讲解https://www.bilibili.com/video/BV…...
[python] 代码工具箱
在 Python 3 的开发过程中,有一些小而实用的工具包可以帮助减轻开发负担,提升工作效率。这些工具包通常专注于解决特定问题或提供特定功能,使代码更简洁和可维护。以下是一些常用的工具包,可以简化开发过程: backoff&a…...
Linux——网络基础
计算机网络背景 网络发展 独立模式: 计算机之间相互独立 在早期的时候,计算机之间是相互独立的,此时如果多个计算机要协同完成某种业务,那么就只能等一台计算机处理完后再将数据传递给下一台计算机,然后下一台计算机再进行相应…...
Vue:双token无感刷新
文章目录 初次授权与发放Token:Access Token的作用:Refresh Token的作用:无感刷新:安全机制:后端创建nest项目AppController 添加login、refresh、getinfo接口创建user.dto.tsAppController添加模拟数据 前端Hbuilder创…...
实现一个作用域插槽的场景
vue项目中,插槽slot有三种分别是:默认插槽、具名插槽、作用域插槽。默认插槽和具名插槽在平时的开发中用的比较多,作用域插槽用的相对较少,以前我对作用域插槽不是很理解,现在理解了一下。下面通过代码来实现一个作用域…...
Qt QPainter的使用方法
重点: 1.QPainter在QWidget窗口的paintEvent中使用。 2.QPainter通常涉及到设置画笔、设置画刷、绘图(QPen、QBrush、drawxx)三个流程。 class Widget : public QWidget {Q_OBJECTprotected:void paintEvent(QPaintEvent *event) Q_DEC…...
低代码:数智化助力新农业发展
随着科技的飞速发展和数字化转型的深入推进,低代码开发平台正逐渐成为软件开发的热门话题。尤其在农业领域,低代码技术为传统农业注入了新的活力,助力新农业实现高效、智能的发展。 低代码开发平台的概念与特点 随着科技的飞速发展࿰…...
3d模型怎么镜像?3d模型镜像的步骤---模大狮模型网
在3D建模软件中,对3D模型进行镜像操作通常是指沿着某个轴线(如X、Y、Z轴)进行镜像翻转,使模型在该轴线的一侧产生对称的镜像效果。以下是在常见的3D建模软件中对3D模型进行镜像的一般步骤: 3d模型镜像步骤: 选择模型:…...
测试微信模版消息推送
进入“开发接口管理”--“公众平台测试账号”,无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。 获取access_token: 自定义模版消息: 关注测试号:扫二维码关注测试号。 发送模版消息: import requests da…...
基于ASP.NET+ SQL Server实现(Web)医院信息管理系统
医院信息管理系统 1. 课程设计内容 在 visual studio 2017 平台上,开发一个“医院信息管理系统”Web 程序。 2. 课程设计目的 综合运用 c#.net 知识,在 vs 2017 平台上,进行 ASP.NET 应用程序和简易网站的开发;初步熟悉开发一…...
【入坑系列】TiDB 强制索引在不同库下不生效问题
文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...
Linux相关概念和易错知识点(42)(TCP的连接管理、可靠性、面临复杂网络的处理)
目录 1.TCP的连接管理机制(1)三次握手①握手过程②对握手过程的理解 (2)四次挥手(3)握手和挥手的触发(4)状态切换①挥手过程中状态的切换②握手过程中状态的切换 2.TCP的可靠性&…...
五年级数学知识边界总结思考-下册
目录 一、背景二、过程1.观察物体小学五年级下册“观察物体”知识点详解:由来、作用与意义**一、知识点核心内容****二、知识点的由来:从生活实践到数学抽象****三、知识的作用:解决实际问题的工具****四、学习的意义:培养核心素养…...
python如何将word的doc另存为docx
将 DOCX 文件另存为 DOCX 格式(Python 实现) 在 Python 中,你可以使用 python-docx 库来操作 Word 文档。不过需要注意的是,.doc 是旧的 Word 格式,而 .docx 是新的基于 XML 的格式。python-docx 只能处理 .docx 格式…...
成都鼎讯硬核科技!雷达目标与干扰模拟器,以卓越性能制胜电磁频谱战
在现代战争中,电磁频谱已成为继陆、海、空、天之后的 “第五维战场”,雷达作为电磁频谱领域的关键装备,其干扰与抗干扰能力的较量,直接影响着战争的胜负走向。由成都鼎讯科技匠心打造的雷达目标与干扰模拟器,凭借数字射…...
R语言速释制剂QBD解决方案之三
本文是《Quality by Design for ANDAs: An Example for Immediate-Release Dosage Forms》第一个处方的R语言解决方案。 第一个处方研究评估原料药粒径分布、MCC/Lactose比例、崩解剂用量对制剂CQAs的影响。 第二处方研究用于理解颗粒外加硬脂酸镁和滑石粉对片剂质量和可生产…...
GruntJS-前端自动化任务运行器从入门到实战
Grunt 完全指南:从入门到实战 一、Grunt 是什么? Grunt是一个基于 Node.js 的前端自动化任务运行器,主要用于自动化执行项目开发中重复性高的任务,例如文件压缩、代码编译、语法检查、单元测试、文件合并等。通过配置简洁的任务…...
Selenium常用函数介绍
目录 一,元素定位 1.1 cssSeector 1.2 xpath 二,操作测试对象 三,窗口 3.1 案例 3.2 窗口切换 3.3 窗口大小 3.4 屏幕截图 3.5 关闭窗口 四,弹窗 五,等待 六,导航 七,文件上传 …...
