MongoDb - 使用 Mongo Shell 更新 object 中的所有属性
MongoDb - Update all properties in an object using MongoShell
我有一个 collection,其中包含许多包含运费的文件:
{
"_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.
能否请您指导我编写请求的正确方法?
我可能错了,但看起来目前不支持此功能 - 实际上有一个开放的 jira-issue 解决了这个主题。不过看起来这不会被实施。
您可以在更新中使用聚合管道。 $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供您参考。
您可以使用聚合框架来完成:
$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
})
我有一个 collection,其中包含许多包含运费的文件:
{
"_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.
能否请您指导我编写请求的正确方法?
我可能错了,但看起来目前不支持此功能 - 实际上有一个开放的 jira-issue 解决了这个主题。不过看起来这不会被实施。
您可以在更新中使用聚合管道。 $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供您参考。
您可以使用聚合框架来完成:
$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
})