我收集了这样的数据:
{
"items": [
{
"product": {
"name": "prod1",
"price": {
"pledge": 1,
"cost": 19
}
}
},
{
"product": {
"name": "prod2",
"price": {
"pledge": 2,
"cost": 10
}
}
}
]
}
我想更新整个集合,让它们像这样:
{
"items": [
{
"product": {
"name": "prod1",
"price": {
"pledge": 1,
"deposit": 1,
"cost": 19
}
}
},
{
"product": {
"name": "prod2",
"price": {
"pledge": 2,
"deposit": 2,
"cost": 10
}
}
}
]
}
对于
price
中的每个 items
,我想在同一元素中添加一个名为 deposit
的新字段,其值为 pledge
的值。
我怎样才能以优化的方式做到这一点?
您应该需要使用聚合管道更新查询来引用该字段。
$map
- 迭代 items
数组中的元素1.1。
$mergeObjects
- 将当前迭代对象与具有 price
字段的文档合并。
1.1.1。
$mergeObjects
- 将 product.price
对象与引用 deposit
值的 product.price.pledge
字段的文档合并。
db.collection.update({},
[
{
$set: {
items: {
$map: {
input: "$items",
in: {
product: {
$mergeObjects: [
"$$this.product",
{
"price": {
$mergeObjects: [
"$$this.product.price",
{
deposit: "$$this.product.price.pledge"
}
]
}
}
]
}
}
}
}
}
}
])
您可以为此使用 updateMany() 。
db.collectionName.updateMany(
{}, // Match all documents
{
$set: {
"items.$[elem].product.price.deposit": "$items.$[elem].product.price.pledge"
}
},
{
arrayFilters: [{"elem.product.price.pledge": {$exists: true}}], // Filter to match all documents that have the pledge field
multi: true // Apply to all documents
}
)
updateMany
定位集合中的所有文档({} 作为第一个
论证)。$set
运算符用于为存款字段分配一个等于
到每个项目的每个价格对象内的质押字段
项目数组。arrayFilters
指定元素的条件
更新应适用于。在这里,它确保操作仅适用
到存在承诺的元素。multi: true
选项虽然在 updateMany 中是多余的,但强调了
更新多个文档的意图。它更相关于
更新操作。注意:将 collectionName 替换为您的集合的正确名称。