$setField(聚合)
定义
$setField
版本 5.0 中的新增功能。
添加、更新或删除文档中的指定字段。
您可以使用
$setField
添加、更新或删除名称包含句点 (.
) 或以美元符号 ($
) 开头的字段。
语法
$setField
通过以下语法实现:
{ $setField: { field: <String>, input: <Object>, value: <Expression> } }
您必须提供以下字段:
行为
如果
input
的计算结果为missing
、undefined
或null
,$setField
返会回null
,而不更新input
。如果
input
的计算结果为对象、missing
、undefined
或null
以外的任何值,$setField
将返回错误。如果
field
的解析结果不是字符串常量,$setField
将返回错误。如果
input
中不存在field
,$setField
会进行添加。$setField
不会隐式遍历对象或数组。例如,$setField
将"a.b.c"
的field
值计算为顶级字段"a.b.c"
,而不是嵌套字段{ "a": { "b": { "c": } } }
。$unsetField
是输入值为$$REMOVE
的$setField
的别名。以下表达式具有同等效果:{ $setField: { field: <field name>, input: "$$ROOT", value: "$$REMOVE" } } { $unsetField: { field: <field name>, input: "$$ROOT" } }
示例
添加包含句点 (.
) 的字段
考虑包含以下文档的 inventory
集合:
db.inventory.insertMany( [ { "_id" : 1, "item" : "sweatshirt", price: 45.99, qty: 300 } { "_id" : 2, "item" : "winter coat", price: 499.99, qty: 200 } { "_id" : 3, "item" : "sun dress", price: 199.99, qty: 250 } { "_id" : 4, "item" : "leather boots", price: 249.99, qty: 300 } { "_id" : 5, "item" : "bow tie", price: 9.99, qty: 180 } ] )
以下操作使用 $replaceWith
管道阶段和 $setField
操作符为每份文档添加一个新字段 "price.usd"
。每份文档中 "price.usd"
的值将等于 "price"
的值。最后,该操作使用 $unset
管道阶段移除 "price"
字段。
db.inventory.aggregate( [ { $replaceWith: { $setField: { field: "price.usd", input: "$$ROOT", value: "$price" } } }, { $unset: "price" } ] )
操作返回以下结果:
[ { _id: 1, item: 'sweatshirt', qty: 300, 'price.usd': 45.99 }, { _id: 2, item: 'winter coat', qty: 200, 'price.usd': 499.99 }, { _id: 3, item: 'sun dress', qty: 250, 'price.usd': 199.99 }, { _id: 4, item: 'leather boots', qty: 300, 'price.usd': 249.99 }, { _id: 5, item: 'bow tie', qty: 180, 'price.usd': 9.99 } ]
添加以美元符号 ($
) 开头的字段
考虑包含以下文档的 inventory
集合:
db.inventory.insertMany( [ { "_id" : 1, "item" : "sweatshirt", price: 45.99, qty: 300 } { "_id" : 2, "item" : "winter coat", price: 499.99, qty: 200 } { "_id" : 3, "item" : "sun dress", price: 199.99, qty: 250 } { "_id" : 4, "item" : "leather boots", price: 249.99, qty: 300 } { "_id" : 5, "item" : "bow tie", price: 9.99, qty: 180 } ] )
以下操作使用 $replaceWith
管道阶段以及 $setField
和 $literal
操作符为每个文档添加一个新字段 "$price"
。每个文档中 "$price"
的值将等于 "price"
的值。最后,该操作使用 $unset
管道阶段移除 "price"
字段。
db.inventory.aggregate( [ { $replaceWith: { $setField: { field: { $literal: "$price" }, input: "$$ROOT", value: "$price" } } }, { $unset: "price" } ] )
操作返回以下结果:
[ { _id: 1, item: 'sweatshirt', qty: 300, '$price': 45.99 }, { _id: 2, item: 'winter coat', qty: 200, '$price': 499.99 }, { _id: 3, item: 'sun dress', qty: 250, '$price': 199.99 }, { _id: 4, item: 'leather boots', qty: 300, '$price': 249.99 }, { _id: 5, item: 'bow tie', qty: 180, '$price': 9.99 } ]
更新包含句点 (.
) 的字段
考虑包含以下文档的 inventory
集合:
db.inventory.insertMany( [ { _id: 1, item: 'sweatshirt', qty: 300, 'price.usd': 45.99 }, { _id: 2, item: 'winter coat', qty: 200, 'price.usd': 499.99 }, { _id: 3, item: 'sun dress', qty: 250, 'price.usd': 199.99 }, { _id: 4, item: 'leather boots', qty: 300, 'price.usd': 249.99 }, { _id: 5, item: 'bow tie', qty: 180, 'price.usd': 9.99 } ] )
以下操作使用 $match
管道阶段查找特定文档,并使用 $replaceWith
管道阶段以及 $setField
操作符更新匹配文档中的 "price.usd"
字段:
db.inventory.aggregate( [ { $match: { _id: 1 } }, { $replaceWith: { $setField: { field: "price.usd", input: "$$ROOT", value: 49.99 } } } ] )
操作返回以下结果:
[ { _id: 1, item: 'sweatshirt', qty: 300, 'price.usd': 49.99 } ]
更新以美元符号 ($
) 开头的字段
考虑包含以下文档的 inventory
集合:
db.inventory.insertMany([ { _id: 1, item: 'sweatshirt', qty: 300, '$price': 45.99 }, { _id: 2, item: 'winter coat', qty: 200, '$price': 499.99 }, { _id: 3, item: 'sun dress', qty: 250, '$price': 199.99 }, { _id: 4, item: 'leather boots', qty: 300, '$price': 249.99 }, { _id: 5, item: 'bow tie', qty: 180, '$price': 9.99 } ] )
以下操作使用 $match
管道阶段查找特定文档,使用 $replaceWith
管道阶段以及 $setField
和 $literal
操作符更新匹配文档中的 "$price"
字段:
db.inventory.aggregate( [ { $match: { _id: 1 } }, { $replaceWith: { $setField: { field: { $literal: "$price" }, input: "$$ROOT", value: 49.99 } } } ] )
操作返回以下结果:
[ { _id: 1, item: 'sweatshirt', qty: 300, '$price': 49.99 } ]
删除包含句点 (.
) 的字段
考虑包含以下文档的 inventory
集合:
db.inventory.insertMany([ { _id: 1, item: 'sweatshirt', qty: 300, 'price.usd': 45.99 }, { _id: 2, item: 'winter coat', qty: 200, 'price.usd': 499.99 }, { _id: 3, item: 'sun dress', qty: 250, 'price.usd': 199.99 }, { _id: 4, item: 'leather boots', qty: 300, 'price.usd': 249.99 }, { _id: 5, item: 'bow tie', qty: 180, 'price.usd': 9.99 } ] )
以下操作使用 $replaceWith
管道阶段、$setField
操作符和 $$REMOVE
从每个文档中删除 "price.usd"
字段:
db.inventory.aggregate( [ { $replaceWith: { $setField: { field: "price.usd", input: "$$ROOT", value: "$$REMOVE" } } } ] )
操作返回以下结果:
[ { _id: 1, item: 'sweatshirt', qty: 300 }, { _id: 2, item: 'winter coat', qty: 200 }, { _id: 3, item: 'sun dress', qty: 250 }, { _id: 4, item: 'leather boots', qty: 300 }, { _id: 5, item: 'bow tie', qty: 180 } ]
使用 $unsetField
别名写入的类似查询会返回相同的结果:
db.inventory.aggregate( [ { $replaceWith: { $unsetField: { field: "price.usd", input: "$$ROOT" } } } ] )
删除以美元符号 ($
) 开头的字段
考虑包含以下文档的 inventory
集合:
db.inventory.insertMany( [ { _id: 1, item: 'sweatshirt', qty: 300, '$price': 45.99 }, { _id: 2, item: 'winter coat', qty: 200, '$price': 499.99 }, { _id: 3, item: 'sun dress', qty: 250, '$price': 199.99 }, { _id: 4, item: 'leather boots', qty: 300, '$price': 249.99 }, { _id: 5, item: 'bow tie', qty: 180, '$price': 9.99 } } )
以下操作使用 $replaceWith
管道阶段、$setField
和 $literal
操作符以及 $$REMOVE
从每份文档中删除 "$price"
字段:
db.inventory.aggregate( [ { $replaceWith: { $setField: { field: { $literal: "$price" }, input: "$$ROOT", value: "$$REMOVE" } } } ] )
操作返回以下结果:
[ { _id: 1, item: 'sweatshirt', qty: 300 }, { _id: 2, item: 'winter coat', qty: 200 }, { _id: 3, item: 'sun dress', qty: 250 }, { _id: 4, item: 'leather boots', qty: 300 }, { _id: 5, item: 'bow tie', qty: 180 } ]
使用 $unsetField
别名写入的类似查询会返回相同的结果:
db.inventory.aggregate( [ { $replaceWith: { $unsetField: { field: { $literal: "$price" }, input: "$$ROOT" } } } ] )