对于 AI 代理:可在 https://www.mongodb.com/zh-cn/docs/llms.txt 获取文档索引—通过在任何 URL 路径后添加 .md 可获取所有页面的 Markdown 版本。
Docs 菜单

$replaceWith(聚合阶段)

$replaceWith

Replaces the input document with the specified document. The operation replaces all existing fields in the input document, including the _id field. With $replaceWith, you can promote an embedded document to the top-level. You can also specify a new document as the replacement.

The $replaceWith stage performs the same action as the $replaceRoot stage, but the stages have different forms.

The $replaceWith stage has the following form:

{ $replaceWith: <replacementDocument> }

替换文档可以是任何解析为文档的有效表达式。有关表达式的更多信息,请参阅表达式。

If the <replacementDocument> is not a document, $replaceWith errors and fails.

If the <replacementDocument> resolves to a missing document (i.e. the document does not exist), $replaceWith errors and fails. For example, create a collection with the following documents:

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

Then the following $replaceWith operation fails because one of the document does not have the name field:

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

为避免错误,可以使用 $mergeObjects 将 name 文档与某份默认文档合并;例如:

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

Alternatively, you can skip the documents that are missing the name field by including a $match stage to check for existence of the document field before passing documents to the $replaceWith stage:

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

The following operation uses the $replaceWith stage to replace each input document with the result of a $mergeObjects operation. The $mergeObjects expression merges the specified default document with the pets document.

db.people.aggregate( [
{ $replaceWith: { $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 }
]

一个名为 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 } } },
{ $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 }
]

使用以下文档填充的示例集合 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" }
])

Assume that for reporting purposes, you want to calculate for each completed sale, the total amount as of the current report run time. The following operation finds all the sales with status C and creates new documents using the $replaceWith stage. The $replaceWith calculates the total amount as well as uses the variable NOW to get the current time.

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: '...' },
{ _id: 3, item: 'jam', amount: 50, status: 'Complete', asofDate: '...' },
{ _id: 4, item: 'muffins', amount: 50, status: 'Complete', asofDate: '...' }
]

示例集合 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" } }
] )
第一个阶段:

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

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

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

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

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

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

The $replaceWith uses the $arrayToObject to convert the items2 into a document, using the specified key k and value v pairs and outputs that document to the next stage. For example:

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

该聚合返回以下文档:

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

使用以下文档创建名为 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" }
] )

The following operation uses $replaceWith with $mergeObjects to output current documents with default values for missing fields:

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: '987-654-3210',
home: ''
}
]

要学习;了解有关相关管道阶段的更多信息,请参阅 $replaceRoot 指南。

给本页内容打分