MongoDb - 使用 MongoShell 更新对象中的所有属性
Posted
技术标签:
【中文标题】MongoDb - 使用 MongoShell 更新对象中的所有属性【英文标题】:MongoDb - Update all properties in an object using MongoShell 【发布时间】:2022-01-22 04:41:37 【问题描述】:我收藏了许多包含运费的文件:
"_id":
"$oid": "5f7439c3bc3395dd31ca4f19"
,
"adapterKey": "transport1",
"pricegrid":
"10000": 23.66,
"20000": 23.75,
"30000": 23.83,
"31000": 43.5,
"40000": 44.16,
"50000": 49.63,
"60000": 50.25,
"70000": 52,
"80000": 56.62,
"90000": 59,
"100000": 62.5,
"119000": 68.85,
"149000": 80,
"159000": 87,
"179000": 94,
"199000": 100.13,
"249000": 118.5,
"299000": 138.62,
"999000": 208.63
,
"zones": [
"25"
],
"franco": null,
"tax": 20,
"doc_created":
"$date": "2020-09-30T07:54:43.966Z"
,
"idConfig": "0000745",
"doc_modified":
"$date": "2020-09-30T07:54:43.966Z"
在pricegrid
中,所有属性都可以从一个网格到另一个网格不同。
我想更新“pricegrid”字段中的所有价格(价格 * 1.03 + 1)。
我试过这个:
db.shipping_settings.updateMany(
'adapterKey': 'transport1' ,
$mul: 'pricegrid.$': 1.03 ,
$inc: 'pricegrid.$': 1
)
导致这个错误:
MongoServerError: Updating the path 'pricegrid.$' would create a conflict at 'grille.$'
所以我只尝试了 $mul(计划在另一个查询中执行 $inc):
db.livraison_config.updateMany(
'adapterKey': 'transport1' ,
$mul: 'pricegrid.$': 1.03
)
但在这种情况下,我会收到此错误:
MongoServerError: The positional operator did not find the match needed from the query.
能否请您指导我写请求的正确方法?
【问题讨论】:
【参考方案1】:您可以在更新中使用聚合管道。 $objectToArray
pricegrid
首先将其转换为 k-v 元组数组。然后,执行$map
来执行计算。最后,$arrayToObject
将其转换回来。
db.collection.update(
"adapterKey": "transport1"
,
[
$set:
pricegrid:
"$objectToArray": "$pricegrid"
,
"$set":
"pricegrid":
"$map":
"input": "$pricegrid",
"as": "p",
"in":
"k": "$$p.k",
"v":
"$add": [
"$multiply": [
"$$p.v",
1.03
]
,
1
]
,
$set:
pricegrid:
"$arrayToObject": "$pricegrid"
])
这里是Mongo playground 供您参考。
【讨论】:
谢谢,这正是我所期待的。我以前经常使用 mysql,但对 Mongo 聚合管道还不熟悉。【参考方案2】:您可以使用聚合框架来做到这一点:
$objectToArray
- 将 pricegrid 对象转换为数组,以便您可以迭代其项目
$map
遍历上一步生成的数组
$sum
和 multiply
执行数学运算
$arrayToObject
将更新后的数组转换回对象
db.collection.update(
"adapterKey": "transport1"
,
[
"$set":
"pricegrid":
"$arrayToObject":
"$map":
"input":
"$objectToArray": "$pricegrid"
,
"in":
k: "$$this.k",
v:
"$sum": [
1,
"$multiply": [
"$$this.v",
1.02
]
]
],
"multi": true
)
Working example
【讨论】:
感谢您的解释。我接受了雷的回答,因为它比你早几分钟发布,但也赞成你的回答。【参考方案3】:我可能错了,但目前似乎不支持此功能 - 实际上有一个开放的jira-issue 解决了这个主题。不过看起来这不会实现。
【讨论】:
以上是关于MongoDb - 使用 MongoShell 更新对象中的所有属性的主要内容,如果未能解决你的问题,请参考以下文章