MongoDB 4.2.22使用$replaceOne报错,寻求兼容替代方案
兼容MongoDB 4.2的字符串替换updateMany方案
问题背景
尝试运行以下updateMany查询替换集合中的指定字符串模式:
db.collection.updateMany({ lastImageUrl: { "$regex": "kidplus-bucket-eu" } }, [ { $set: { videos: { high: { videoUrl: { $replaceOne: { input: "$lastImageUrl", find: "/kidplus-bucket-eu", replacement: "/kidplus-bucket-demo" } } } } } }, { $set: { videos: { high: { videoUrl: { $replaceOne: { input: "$lastImageUrl", find: "/kidplus-bucket-eu", replacement: "/kidplus-bucket-demo" } } } } } }, { $set: { lastImageUrl: { $replaceOne: { input: "$lastImageUrl", find: "/kidplus-bucket-eu", replacement: "/kidplus-bucket-demo" } } } } ])
但报错:MongoError: Unrecognized expression '$replaceOne',改用$replaceAll后仍报相同错误。原因是MongoDB版本为4.2.22,而$replaceOne/$replaceAll是4.4版本才引入的,需要兼容4.2的替代方案。
替代实现方案
MongoDB 4.2可通过$split结合$concat实现字符串替换逻辑,以下是修改后的updateMany查询:
db.collection.updateMany( { lastImageUrl: { "$regex": "kidplus-bucket-eu" } }, [ { $set: { // 替换lastImageUrl字段 lastImageUrl: { $concat: [ { $arrayElemAt: [{ $split: ["$lastImageUrl", "/kidplus-bucket-eu"] }, 0] }, "/kidplus-bucket-demo", { $arrayElemAt: [{ $split: ["$lastImageUrl", "/kidplus-bucket-eu"] }, 1] } ] }, // 替换videos.high.videoUrl字段(合并原查询中重复的两次操作) "videos.high.videoUrl": { $concat: [ { $arrayElemAt: [{ $split: ["$lastImageUrl", "/kidplus-bucket-eu"] }, 0] }, "/kidplus-bucket-demo", { $arrayElemAt: [{ $split: ["$lastImageUrl", "/kidplus-bucket-eu"] }, 1] } ] } } } ] )
逻辑说明
$split:将目标字符串按匹配串/kidplus-bucket-eu拆分为数组,例如原字符串https://kidplus-bucket-eu/path/to/image会被拆分为["https://", "/path/to/image"]$arrayElemAt:提取拆分后数组的前缀(索引0)和后缀(索引1)部分$concat:将前缀、替换串、后缀拼接为完整的替换后字符串
注意事项
- 原查询中重复处理了两次
videos.high.videoUrl,合并为一次操作可提升执行效率 - 该方案仅替换第一个匹配的字符串;若需全局替换所有匹配项,需嵌套多层
$split和$concat,或优先考虑升级MongoDB版本至4.4+
内容的提问来源于stack exchange,提问作者Omer Eshed
相关产品推荐
相关产品推荐

