MongoDB - 使用嵌入数组元素中的子字符串更新值

问题描述 投票:0回答:1

这是我的数据架构:

{
    _id: ...,
    videos: [
       {
        "url" : <some url>,
        "converted" : true,
         ...
         "resolutions": [
             {
               "file_url": <some_url>,
               "details": {...}
             },
             {
               "file_url": <some_url>,
               "details": {...}
             },
             {
               "file_url": <some_url>,
               "details": {...}
             }
            }, 
            {video_2}, 
            {video_N}
         ]
            
       }

    ]
}

每个元素都有一个

videos
数组以及一个
resolutions
嵌套数组。 我需要更新每个
resolutions.file_url
并用新域名替换旧域名。

所以我需要将“old_url.com/”替换为“new_url.com/”。

这是我为此所做的查询:

var oldUrl = "old_url.com/";
var newUrl = "new_url.com/";


db.getCollection('projects').update(
    {
        "videos.resolutions.file_url": {$regex: oldUrl},
        "videos.converted": true
    },
    {
        "$set": {
            "videos.$[elem].resolutions.$.file_url": ????
        }
    },
    {
        "arrayFilters": [{"elem.resolutions.file_url": {$regex: oldUrl}}],
        "multi": true
    }
)

它可以很好地处理一些静态数据,我可以用“hello world”更新所有道具,但不确定如何根据当前的

videos.$[elem].resolutions.$.file_url
值使该字符串替换正确。

mongodb multidimensional-array aggregation-framework mongodb-update
1个回答
1
投票

我认为这不能在简单的更新查询中完成,特别是如果您想替换字段中的子字符串。

与(更新)聚合查询一起使用,您需要:

  1. $map
    - 迭代
    videos
    数组。覆盖
    resolutions
    数组的匹配元素。

  2. $map
    - 迭代
    resolutions
    数组,如果值满足正则表达式 (
    file_url
    ),则通过替换匹配的子字符串(
    $replaceOne
    $replaceAll
    )来更新文档的
    $regexMatch
    字段。否则,保持原始值。

db.getCollection('projects').update({
  "videos.resolutions.file_url": {
    $regex: oldUrl
    
  },
  "videos.converted": true
},
[
  {
    $set: {
      videos: {
        $map: {
          input: "$videos",
          as: "video",
          in: {
            $cond: {
              if: {
                $eq: [
                  "$video.converted",
                  true
                ]
              },
              then: {
                $mergeObjects: [
                  "$$video",
                  {
                    resolutions: {
                      $map: {
                        input: "$$video.resolutions",
                        as: "resolution",
                        in: {
                          $cond: {
                            if: {
                              $regexMatch: {
                                input: "$$resolution.file_url",
                                regex: oldUrl
                                
                              }
                            },
                            then: {
                              $mergeObjects: [
                                "$$resolution",
                                {
                                  file_url: {
                                    $replaceAll: {
                                      input: "$$resolution.file_url",
                                      find: oldUrl,
                                      replacement: newUrl
                                    }
                                  }
                                }
                              ]
                            },
                            else: "$$resolution"
                          }
                        }
                      }
                    }
                  }
                ]
              },
              else: "$$video"
            }
          }
        }
      }
    }
  }
])

演示@Mongo Playground

© www.soinside.com 2019 - 2024. All rights reserved.