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 遍历上一步生成的数组 $summultiply 执行数学运算 $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 更新对象中的所有属性的主要内容,如果未能解决你的问题,请参考以下文章

MongoDB 显示所有集合中的所有内容

MongoDB—— shell常用命令

MongoDB—— shell常用命令

.net Core MongoDB用法演示

Mac 安装mongodb,运行Yapi

如何在 MongoDB 中加载初始数据?