MongoDB聚合:$replaceRoot

定义

$replaceRoot使用指定的文档替换输入文档。该操作可替换输入文档的所有字段,包括_id字段。可以将内嵌文档提升到顶层,可以为提升文档创建新文档。

注意:

从MongoDB4.2开始增加了$replaceWith,执行与$replaceRoot类似的动作,但形式有所不同。

$replaceRoot阶段有下面的形式:

{ $replaceRoot: { newRoot: <replacementDocument> } }

替换文档可以是任何能解析为文档的表达式,如果<replacementDocument不是一个文档,该阶段操作会出错并失败。

行为

如果<replacementDocument>不是一个文档,$replaceRoot会出错并失败。

如果<replacementDocument>解析为一个错误的文档(如:文档不存在),$replaceRoot将出错并失败,例如,创建下面的一个集合:

db.collection.insertMany([{ "_id": 1, "name" : { "first" : "John", "last" : "Backus" } },{ "_id": 2, "name" : { "first" : "John", "last" : "McCarthy" } },{ "_id": 3, "name": { "first" : "Grace", "last" : "Hopper" } },{ "_id": 4, "firstname": "Ole-Johan", "lastname" : "Dahl" },
])

进行下面的$replaceRoot操作将失败,因为其中的一个文档缺少name字段。

db.collection.aggregate([{ $replaceRoot: { newRoot: "$name" } }
])

为了避免这个错误,可以使用$mergeObjectsname文档合并到缺省文档,例如:

db.collection.aggregate([{ $replaceRoot: { newRoot: { $mergeObjects: [ { _id: "$_id", first: "", last: "" }, "$name" ] } } }
])

换种方式,也可以在$replaceRoot阶段之前,先使用一个$match阶段,跳过缺少name字段的文档:

db.collection.aggregate([{ $match: { name : { $exists: true, $not: { $type: "array" }, $type: "object" } } },{ $replaceRoot: { newRoot: "$name" } }
])

或者,也可以使用$ifNull表达式指定其它文档成为根,例如:

db.collection.aggregate([{ $replaceRoot: { newRoot: { $ifNull: [ "$name", { _id: "$_id", missingName: true} ] } } }
])

举例

$replaceRoot与内嵌文档字段

名为people的集合中有如下文档:

{ "_id" : 1, "name" : "Arlene", "age" : 34, "pets" : { "dogs" : 2, "cats" : 1 } }
{ "_id" : 2, "name" : "Sam", "age" : 41, "pets" : { "cats" : 1, "fish" : 3 } }
{ "_id" : 3, "name" : "Maria", "age" : 25 }

下面的操作使用$replaceRoot阶段替换所有$mergeObjects返回的文档。$mergeObjects表达式使用`pets’合并到指定的默认文档。

db.people.aggregate( [{ $replaceRoot: { newRoot: { $mergeObjects:  [ { dogs: 0, cats: 0, birds: 0, fish: 0 }, "$pets" ] }} }
] )

操作返回下面的结果:

{ "dogs" : 2, "cats" : 1, "birds" : 0, "fish" : 0 }
{ "dogs" : 0, "cats" : 1, "birds" : 0, "fish" : 3 }
{ "dogs" : 0, "cats" : 0, "birds" : 0, "fish" : 0 }

$replaceRoot与内嵌数组文档

一个名为students的集合包含下面的文档:

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 }]}
])

下面的操作将grade大于等于90的内嵌文档提升到顶层:

db.students.aggregate( [{ $unwind: "$grades" },{ $match: { "grades.grade" : { $gte: 90 } } },{ $replaceRoot: { newRoot: "$grades" } }
] )

操作返回下面的结果:

{ "test" : 3, "grade" : 95, "mean" : 85, "std" : 6 }
{ "test" : 1, "grade" : 90, "mean" : 75, "std" : 6 }
{ "test" : 3, "grade" : 91, "mean" : 85, "std" : 4 }

replaceRoot与新创建的文档

可以利用$replaceRoot阶段创建新文档,并替换掉其他全部字段。

一个名为contacts的集合,包含有以下文档:

{ "_id" : 1, "first_name" : "Gary", "last_name" : "Sheffield", "city" : "New York" }
{ "_id" : 2, "first_name" : "Nancy", "last_name" : "Walker", "city" : "Anaheim" }
{ "_id" : 3, "first_name" : "Peter", "last_name" : "Sumner", "city" : "Toledo" }

下面的操作创建的新文档来自于first_namelast_name字段:

db.contacts.aggregate( [{$replaceRoot: {newRoot: {full_name: {$concat : [ "$first_name", " ", "$last_name" ]}}}}
] )

操作返回的结果:

{ "full_name" : "Gary Sheffield" }
{ "full_name" : "Nancy Walker" }
{ "full_name" : "Peter Sumner" }

$replaceRoot与从$$ROOT创建的新文档和缺省文档

创建一个名为contaces集合,并包含以下文档:

db.contacts.insertMany( [{ "_id" : 1, name: "Fred", email: "fred@example.net" },{ "_id" : 2, name: "Frank N. Stine", cell: "012-345-9999" },{ "_id" : 3, name: "Gren Dell", home: "987-654-3210", email: "beo@example.net" }
] )

下面的操作使用$replaceRoot$mergeObjects输出当前文档,缺失的字段使用缺省值:

db.contacts.aggregate( [{ $replaceRoot:{ newRoot:{ $mergeObjects:[{ _id: "", name: "", email: "", cell: "", home: "" },"$$ROOT"]}}}
] )

聚合结果如下:

{_id: 1,name: 'Fred',email: 'fred@example.net',cell: '',home: ''
},
{_id: 2,name: 'Frank N. Stine',email: '',cell: '012-345-9999',home: ''
},
{_id: 3,name: 'Gren Dell',email: 'beo@example.net',cell: '',home: '987-654-3210'
}

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

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

相关文章

网络基础操作练习

知识改变命运&#xff0c;技术就是要分享&#xff0c;有问题随时联系&#xff0c;免费答疑&#xff0c;欢迎联系&#xff01; 手把手教你操作华为设备&#xff0c;新手必看。 实验拓扑图 关于命令行视图 1&#xff09;用户视图 <Huawei> 2&#xff09;系统视图 [Hu…

C++初阶(类中的默认成员函数)

呀哈喽&#xff0c;我是结衣 今天给大家带来的是类里面的默认成员函数&#xff0c;一共有六个默认的成员函数哦&#xff0c;包括构造函数&#xff0c;析构函数&#xff0c;拷贝构造函数&#xff0c;运算符重载函数&#xff0c;const成员函数&#xff0c;那么正篇开始。 文章目…

java常见面试题:请解释一下Java中的常用网络协议,如HTTP、TCP/IP等。

Java是一种广泛使用的编程语言&#xff0c;它提供了丰富的库来支持各种网络协议&#xff0c;如HTTP、TCP/IP等。以下是这些协议的详细解释&#xff1a; HTTP (Hypertext Transfer Protocol)&#xff1a; 用途&#xff1a;HTTP是用于从服务器请求和发送网页的协议。当我们浏览网…

Go语言中的性能考虑和优化

优化您的Go代码以达到最佳性能 性能优化是软件开发的关键方面&#xff0c;无论您使用哪种编程语言。在这篇文章中&#xff0c;我们将探讨Go语言中的性能考虑和优化&#xff0c;Go是一种以其效率而著称的静态类型和编译语言。我们将深入探讨三个关键领域&#xff1a;分析并发代…

pytorch01:概念、张量操作、线性回归与逻辑回归

目录 一、pytorch介绍1.1pytorch简介1.2发展历史1.3pytorch优点 二、张量简介与创建2.1什么是张量&#xff1f;2.2Tensor与Variable2.3张量的创建2.3.1 直接创建torch.tensor()2.3.2 从numpy创建tensor 2.4根据数值创建2.4.1 torch.zeros()2.4.2 torch.zeros_like()2.4.3 torch…

AutoSAR(基础入门篇)4.6-Autosar_BSW的Watchdog功能

Autosar_Watchdog功能 一、Autosar_BSW的Watchdog功能 1、Watchdog组件图 2、架构与术语解释 二、看门狗规范

开源可观测性平台Signoz(四)【链路监控及数据库中间件监控篇】

转载说明&#xff1a;如果您喜欢这篇文章并打算转载它&#xff0c;请私信作者取得授权。感谢您喜爱本文&#xff0c;请文明转载&#xff0c;谢谢。 前文链接&#xff1a; ​​开源可观测性平台Signoz系列&#xff08;一&#xff09;【开篇】​​ ​​开源可观测性平台Signoz&…

CSS之元素转换

我想大家在写代码时有一个疑问&#xff0c;块级元素可以转换成其他元素吗&#xff1f; 让我为大家介绍一下元素转换 1.display:block(转换成块元素) display&#xff1a;block可以把我们的行内元素或者行内块元素转换成块元素 接下来让我为大家演示一下&#xff1a; <!DO…

tcpdump出现permission denied

在使用tcpdump -i eth0 src host 192.168.0.184 and ip and port 22 -nn -w ping.pacp命令抓包并把抓到的数据保存到ping.pacp时&#xff0c;出现了权限错误的报错。但实际上我这里用的是root用户执行的命令。 查阅man手册发现: 在tcpdump中&#xff0c;-Z选项用于在启动数据…

CSS 动态提示框

​​ <template> <div class"terminal-loader"><div class"terminal-header"><div class"terminal-title">提示框</div><div class"terminal-controls"><div class"control close"…

【Matlab】BP 神经网络时序预测算法

资源下载&#xff1a; https://download.csdn.net/download/vvoennvv/88681507 一&#xff0c;概述 BP 神经网络是一种常见的人工神经网络&#xff0c;也是一种有监督学习的神经网络。其全称为“Back Propagation”&#xff0c;即反向传播算法。BP 神经网络主要由输入层、隐藏层…

网络通信之TCP和UDP-入门2

TCP/IP协议族为运输层指明了两个协议&#xff1a;TCP&#xff08;优点是可靠&#xff0c;缺点慢 &#xff09;和UDP&#xff08;优点快&#xff0c;缺点没有纠错&#xff09;&#xff0c;它们都是作为应同程序和网络操作的中介物。 TCP连接的建立和释放&#xff1a; https://zh…

SpringValidation自定义注解以及分组校验

SpringValidation的参数校验使用可参考&#xff1a;【SpringMVC应用篇】Spring Validation 参数校验-CSDN博客 目录 1. 引入依赖 2. 自定义注解校验 2.1 创建Validation类 2.2 创建注解对象 2.3 使用注解 3. 分组校验 3.1 实体类内部定义接口 3.2 在参数上指定分组 1. …

git回滚操作,常用场景

文章目录 git回滚操作1.git reset --hard 【版本号】2.回滚后的版本v2又想回到之前的版本v32.1 git reflog 3.git checkout -- 文件名4.git reset HEAD 文件名 git回滚操作 假设我们现在有三个版本 现在回滚一个版本 1.git reset --hard 【版本号】 发现只剩下两个版本了 2.…

51单片机的中断相关知识

51单片机的中断相关知识点 一、中断概念和功能 概念 程序执行过程中CPU会遇到一些特殊情况&#xff0c;是正在执行的程序被“中断”&#xff0c;cpu中止原来正在执行的程序&#xff0c;转到处理异常情况或特殊事件的程序去执行&#xff0c;结束后再返回到原被中止的程序处(断…

计算机网络——计算大题(七)

前言&#xff1a; 最近也是在准备计算机考试&#xff0c;我们的考试形式是上机考试&#xff0c;所以可能有些计算题是会给提供思路的&#xff0c;前面已经对本学期的计算机网络知识有了一个简单的认识与了解&#xff0c;现在我们就来对计算大题进行一个学习吧&#xff0c;这里的…

中医电子处方系统,西医个体诊所门诊卫生室病历记录查询软件教程

中医电子处方系统&#xff0c;西医个体诊所门诊卫生室病历记录查询软件教程 一、软件程序问答 1、电子处方软件如何快速开单&#xff1f; 如下图&#xff0c;软件以 佳易王诊所电子处方管理系统V17.1版本为例说明 在开电子处方的时候可以按单个药品开&#xff0c;也可以直…

面试 Java 基础八股文五问五答第六期

面试 Java 基础八股文五问五答第六期 作者&#xff1a;程序员小白条 相信看了本文后&#xff0c;对你的面试是有一定帮助的&#xff01; ⭐点赞⭐收藏⭐不迷路&#xff01;⭐ 1&#xff09;什么是跨域&#xff1f; 跨域问题是指在浏览器中&#xff0c;由于同源策略的限制&am…

【开源】基于Vue+SpringBoot的二手车交易系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 二手车档案管理模块2.3 车辆预约管理模块2.4 车辆预定管理模块2.5 车辆留言板管理模块2.6 车辆资讯管理模块 三、系统设计3.1 E-R图设计3.2 可行性分析3.2.1 技术可行性分析3.2.2 操作可行性3.2.3 经济…

结构体:子网掩码

#include<iostream> using namespace std; union IP //创建共用体 {unsigned char a[4];unsigned int ip; }; IP getIP() //获取ip函数 {int a, b, c, d;scanf_s("%d.%d.%d.%d", &a, &b, &c, &d);IP address;address.a[3] a; address.a[2] …