代码编织梦想

r e p l a c e W i t h ‘ 可以将输入文档替换为指定的文档。该操作可以替换输入文档的所有字段,包括 ‘ i d ‘ 字段。使用 ‘ replaceWith`可以将输入文档替换为指定的文档。该操作可以替换输入文档的所有字段,包括`_id`字段。使用` replaceWith可以将输入文档替换为指定的文档。该操作可以替换输入文档的所有字段,包括id字段。使用replaceWith还可以将内嵌文档提升到最顶级,也可以把它替换掉。替换文档可以是任何能够解析为文档的有效表达式。 r e p l a c e W i t h ‘ 与 ‘ replaceWith`与` replaceWithreplaceRoot`有很多相似点,但也有一些不同点。

语法

{ $replaceWith: <replacementDocument> }

使用

如果<replacementDocument>不是一个文档或者被解析为一个错误的文档(如:文档不存在),都会失败,例如:使用下面的文档创建一个集合:

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

下面的$replaceWith会操作失败,因为最后一个文档缺少name字段:

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

要避免上面的错误,可以使用$mergeObjectsname文档与某个缺省文档合并,如:

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

也可以使用$match阶段,在$replaceWith之前筛选掉name字段异常的数据:

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

亦或者使用$ifNull表达式来指定其它的文档,如:

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

举例:

替换内嵌文档字段

使用下面的语句创建一个people集合:

db.people.insertMany([
   { "_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 }
])

下面的操作对people集合中的内嵌字段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 }

使用嵌套的数组中文档替换

student集合有下面内容:

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 } } },
   { $replaceWith: "$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 }

使用新创建的文档替换

例1

集合sales包含以下文档:

db.sales.insertMany([
   { "_id" : 1, "item" : "butter", "price" : 10, "quantity": 2, date: ISODate("2019-03-01T08:00:00Z"), status: "C" },
   { "_id" : 2, "item" : "cream", "price" : 20, "quantity": 1, date: ISODate("2019-03-01T09:00:00Z"), status: "A" },
   { "_id" : 3, "item" : "jam", "price" : 5, "quantity": 10, date: ISODate("2019-03-15T09:00:00Z"), status: "C" },
   { "_id" : 4, "item" : "muffins", "price" : 5, "quantity": 10, date: ISODate("2019-03-15T09:00:00Z"), status: "C" }
])

假设为了要计算已完成销售的总金额,即查找所有状态为C的销售记录,使用$replaceWith阶段创建新文档计算总金额,并使用变量NOW获取当前时间:

db.sales.aggregate([
   { $match: { status: "C" } },
   { $replaceWith: { _id: "$_id", item: "$item", amount: { $multiply: [ "$price", "$quantity"]}, status: "Complete", asofDate: "$$NOW" } }
])

操作返回以下结果:

{ "_id" : 1, "item" : "butter", "amount" : 20, "status" : "Complete", "asofDate" : ISODate("2019-06-03T22:47:54.812Z") }
{ "_id" : 3, "item" : "jam", "amount" : 50, "status" : "Complete", "asofDate" : ISODate("2019-06-03T22:47:54.812Z") }
{ "_id" : 4, "item" : "muffins", "amount" : 50, "status" : "Complete", "asofDate" : ISODate("2019-06-03T22:47:54.812Z") }
例2

reportedsales集合按季度和地区填入报销售额信息,如下:

db.reportedsales.insertMany( [
   { _id: 1, quarter: "2019Q1", region: "A", qty: 400 },
   { _id: 2, quarter: "2019Q1", region: "B", qty: 550 },
   { _id: 3, quarter: "2019Q1", region: "C", qty: 1000 },
   { _id: 4, quarter: "2019Q2", region: "A", qty: 660 },
   { _id: 5, quarter: "2019Q2", region: "B", qty: 500 },
   { _id: 6, quarter: "2019Q2", region: "C", qty: 1200 }
] )

假设出于报告目的,想查看按季度报告的销售数据,例如

{ "_id" : "2019Q1", "A" : 400, "B" : 550, "C" : 1000 }

可以使用下面的聚合管道:

db.reportedsales.aggregate( [
   { $addFields: { obj:  { k: "$region", v: "$qty" } } },
   { $group: { _id: "$quarter", items: { $push: "$obj" } } },
   { $project: { items2: { $concatArrays: [ [ { "k": "_id", "v": "$_id" } ], "$items" ] } } },
   { $replaceWith: { $arrayToObject: "$items2" } }
] )
阶段1

$addFields阶段添加了一个新的obj文档字段,该字段将关键字k定义为区域值,将值v定义为该区域的数量。例如

{ "_id" : 1, "quarter" : "2019Q1", "region" : "A", "qty" : 400, "obj" : { "k" : "A", "v" : 400 } }
阶段2

$group阶段按季度分组,并使用$pushobj字段累加到一个新的items数组字段中。例如:

{ "_id" : "2019Q1", "items" : [ { "k" : "A", "v" : 400 }, { "k" : "B", "v" : 550 }, { "k" : "C", "v" : 1000 } ] }
阶段3

$project阶段使用$concatArrays创建一个新数组items2,其中包括_id信息和items数组中的元素:

{ "_id" : "2019Q1", "items2" : [ { "k" : "_id", "v" : "2019Q1" }, { "k" : "A", "v" : 400 }, { "k" : "B", "v" : 550 }, { "k" : "C", "v" : 1000 } ] }
阶段4

$replaceWith使用$arrayToObjectitems2转换成文档,使用kv键值对,并将文档输出到下一阶段。例如:

{ "_id" : "2019Q1", "A" : 400, "B" : 550, "C" : 1000 }

最终的执行结果:

{ "_id" : "2019Q1", "A" : 400, "B" : 550, "C" : 1000 }
{ "_id" : "2019Q2", "A" : 660, "B" : 500, "C" : 1200 }

使用$$ROOT创建的新文档和默认文档替换

创建contacts集合:

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", cell: "987-654-3210", email: "beo@example.net" }
] )

下面使用$replaceWith$mergeObjects输出当前文档中缺失字段的默认值:

db.contacts.aggregate( [
   { $replaceWith:
      { $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'
}
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/superatom01/article/details/136093636

MongoDb聚合操作之replaceRoot-爱代码爱编程

replaceRoot语法 固定语法结构如下: { $replaceRoot: { newRoot: <replacementDocument> } } 其中表达式中的replacementDocument可以是任何可以解析为文档的表达式! 因为在mongodb中的文档为json对象,所以正确的文档对象应该是以键值对的形式存在的,如:

mongodb聚合:$merge 阶段(1)-爱代码爱编程

$merge的用途是把聚合管道产生的结果写入指定的集合,有时候可以用$merge来做物化视图。需要注意,$meger操作必须是聚合管道的最后一个阶段。具体功能有: 能够输出到当前或不同的数据库能够输出到正在聚合的集合(慎重

mongodb聚合:$merge 阶段(2)-爱代码爱编程

$merge的用途是把聚合管道产生的结果写入指定的集合,有时候可以用$merge来做物化视图。下面是$merge的一些例子。 举例 按需物化视图:创建集合 当输出集合不存在时,$merge将自动创建。首先在zoo数据库

mongodb聚合:$replaceroot-爱代码爱编程

定义 $replaceRoot使用指定的文档替换输入文档。该操作可替换输入文档的所有字段,包括_id字段。可以将内嵌文档提升到顶层,可以为提升文档创建新文档。 注意: 从MongoDB4.2开始增加了$replaceW

mongodb 字段中数据类型不一致序列化异常排查与处理-爱代码爱编程

MongoDB 字段中数据类型不一致序列化异常排查与处理 背景如下,因为项目迁移愿意,一个使用Mongodb的业务拥有C#和Java两组Api。Java Api开发和测试都很顺利。上线一段时间后,客服反馈记录都不见了。查看

mongodb的分片集群(二) :mongodb4.x分片集群离线搭建&开启安全认证-爱代码爱编程

转载说明:如果您喜欢这篇文章并打算转载它,请私信作者取得授权。感谢您喜爱本文,请文明转载,谢谢。 相关文章: MongoDB的分片集群(一) : 基础知识 在《MongoDB的分片集群(一) : 基础知识》中梳理了分片集群的基础知识,本文则记录分片集群的离线搭建,并开启集群的安全认证的过程。 这是一篇结合自己踩过的坑,总结的笔记教程。

mongodb系列之wiredtiger引擎-爱代码爱编程

概述 关系型数据库MySQL有InnoDB存储引擎,存储引擎很大程度上决定着数据库的性能。 在MongoDB早期版本中,默认使用MMapV1存储引擎,其索引就是一个B-树(也称B树)。 从MongoDB 3.0开始引入

mongodb的操作和理解-爱代码爱编程

什么是MongoDB? MongoDB:基于分布式文件存储的数据库由C++语言编写。旨在为WEB应用提供可扩展的高性能数据存储解决方案。MongoDB是一个介于关系数据库和非关系数据库(nosql)之间的产品,是非关系数据

51单片机之数码管显示表白数字篇-爱代码爱编程

朝菌不知晦朔 蟪蛄不知春秋 眼界决定境界 CSDN 请求进入专栏                                是否进入《51单片机专栏》? 确定 目录  数码管的简介  数码管引脚定义 数码管的原理图 74HC245 代码实现   静态数码管的显示  动态数码管

51单片机之led灯模块篇-爱代码爱编程

御风以翔 破浪以飏 🎥个人主页 🔥个人专栏 目录 点亮一盏LED灯  LED的组成原理 LED的硬件模型 点亮一盏LED灯的程序设计  LED灯闪烁 LED流水灯   独立按键控制LED灯亮灭 独立按键的组成原理 独立按键的硬件模型   独立按键控制LED灯状态 按键

fastapi使用异步motor实现对mongodb的增删改查-爱代码爱编程

一、环境准备: 需要有mongodb和poetry以及Python3.10+ 二、克隆示例代码到本地 git clone git@github.com:waketzheng/fastapi_async_mongo_demo.git 三、安装依赖 cd fastapi_async_mongo_demo poetry shell poetry ins

mongodb聚合: $sort-爱代码爱编程

聚合的$sort阶段对所有输入文件进行排序,并按排序顺序返回管道。 语法 { $sort: { <field1>: <sort order>, <field2>: <sort o