定义
$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" } } } ] )