通过替换该对象的子字符串来更新嵌套数组对象值 属性

Update nested array object value by replacing substring of that object property

我的 mongodb 集合中有一组名为订单的数据:

{
    "_id" : ObjectId("618e0e1b17687316dcdd6246"),
    "groupUID": "abc",
    "orderData" : {
        "charges" : {
            "total" : 18480.0,
            "subtotal" : 13980.0 
        },
        "items" : [ 
            {
                "name" : "Chocolate cookies",
                "imageURL": "domainURL2.com/cookies"
            },
            {
                "name" : "Chocolate muffins",
                "imageURL": "domainURL2.com/muffins"
            }
        ]
    }
}

现在我想在该集合的每个文档中将“domainURL2”的 imageURL 子字符串部分更新为“domainURL1”字段。到目前为止,我有以下查询:

db.orders.update( { "groupUID" : "abc" }, { "$set": { "orderData.items.$.imageURL":"myURL.com" } } )

我也有 javascript 形式的查询,但我希望它是纯 mongo 查询。所以不幸的是,下面的查询不会为我做。

db.getCollection("orders").find({"groupUID" : "abc"}).forEach(function(aRow) {
    if (aRow.orderDetails !== undefined) {
    var updated = false;
        aRow.orderData.items.forEach(function(item) {

item.imageURL = item.imageURL.replace("eddress/", "noknok-app/");
        })
db.getCollection("orders").save(aRow);
    }
});

我想更新所有记录的 imageURL 字段的子字符串部分。我无法弄清楚查询的其余部分。谁能帮帮我。

我的回答可能看起来很复杂(欢迎 suggestion/improvement)。

使用聚合管道进行更新。

  1. $set - 更新 orderData.items 字段。

    1.1。 $map - 迭代 orderData.items 和 returns 新数组。

    1.1.1。 $mergeObjects - 合并当前对象和来自 1.1.1.1.

    imageURL 字段

    1.1.1.1。 $cond - 使用 $regexMatch 查找以“domainURL2.com”开头的 imageURL

    1.1.1.2。如果为真,则将“domainURL2.com”替换为“domainURL1.com”。

    1.1.1.3。如果为 false,则保留现有值。

db.collection.update({
  "groupUID": "abc"
},
[
  {
    "$set": {
      "orderData.items": {
        $map: {
          input: "$orderData.items",
          in: {
            $mergeObjects: [
              "$$this",
              {
                imageURL: {
                  $cond: {
                    if: {
                      $regexMatch: {
                        input: "$$this.imageURL",
                        regex: "^domainURL2.com"
                      }
                    },
                    then: {
                      $concat: [
                        "domainURL1.com",
                        {
                          $arrayElemAt: [
                            {
                              $split: [
                                "$$this.imageURL",
                                "domainURL2.com"
                              ]
                            },
                            -1
                          ]
                        }
                      ]
                    },
                    else: "$$this.imageURL"
                  }
                }
              }
            ]
          }
        }
      }
    }
  }
])

Sample Mongo Playground


另一种方法是使用 $replaceOne(@rickhg12hs 建议),这会容易得多。

$replaceOne 替换 1.1.1.1.

db.collection.update({
  "groupUID": "abc"
},
[
  {
    "$set": {
      "orderData.items": {
        $map: {
          input: "$orderData.items",
          in: {
            $mergeObjects: [
              "$$this",
              {
                imageURL: {
                  $replaceOne: {
                    input: "$$this.imageURL",
                    find: "domainURL2.com",
                    replacement: "domainURL1.com"
                  }
                }
              }
            ]
          }
        }
      }
    }
  }
])

Sample Mongo Playground ($replaceOne)