在Mongo查询中使用子字符串来更新嵌入的数组元素

问题描述 投票: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}
         ]
            
       }

    ]
}

每个元素都有一系列具有多种分辨率的视频。 我需要更新每个决议.file_url 并用新域名替换旧域名。

所以我需要将

old_url.com/<path>
替换为
new_url.com/<path>

这是我为此所做的查询

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 aggregation-framework
1个回答
0
投票

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

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

  1. $map
    - 迭代
    videos
    数组并覆盖
    resolutions
    数组。

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

db.getCollection('projects')({
  "videos.resolutions.file_url": {
    $regex: oldUrl
  },
  "videos.converted": true
},
[
  {
    $set: {
      videos: {
        $map: {
          input: "$videos",
          as: "video",
          in: {
            $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"
                      }
                    }
                  }
                }
              }
            ]
          }
        }
      }
    }
  }
],
{
  multi: true
})

演示@Mongo Playground

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