MongoDB如何批量更新Image集合中img_uri字段的域名前缀
MongoDB批量替换Image集合字段前缀实现方案
你要实现的是将Image集合内所有img_uri字段的http://localhost:8080前缀统一替换为https://example.com,直接在Mongo Shell执行对应更新语句即可,以下是分版本的可直接运行的方案:
推荐方案(MongoDB 4.2及以上版本)
4.2+版本支持聚合管道更新,可实现原子化批量更新,性能更高,不会出现逐文档更新的并发问题:
// 第一步:先查询匹配的文档,确认范围无误后再执行更新 db.Image.find( { img_uri: /^http:\/\/localhost:8080/ }, { img_uri: 1 } ).limit(20) // 第二步:确认匹配结果正确后,执行批量替换 db.Image.updateMany( // 过滤条件:仅匹配img_uri以本地服务地址开头的文档 { img_uri: /^http:\/\/localhost:8080/ }, [ { $set: { img_uri: { $replaceOne: { input: "$img_uri", find: "http://localhost:8080", replacement: "https://example.com" } }, // 如果需要自动刷新更新时间,保留下面这行,不需要可以删掉 updatedAt: new Date() } } ] )
该方案只会替换字符串开头匹配到的前缀内容,不会影响img_uri后半段的资源路径,更新后的文档结构和你给出的预期结果完全一致。
低版本兼容方案(MongoDB 4.2以下)
如果是4.2以下的老版本,不支持聚合管道更新,可以通过游标遍历匹配文档逐行更新,适合数据量在10万以内的场景:
db.Image.find( { img_uri: /^http:\/\/localhost:8080/ } ).forEach(doc => { const newImgUri = doc.img_uri.replace("http://localhost:8080", "https://example.com"); db.Image.updateOne( { _id: doc._id }, { $set: { img_uri: newImgUri, // 不需要自动更新修改时间可以删掉下面这行 updatedAt: new Date() } } ) })
注意:如果你的集合数据量超过百万,建议给
img_uri字段加普通索引后再执行更新,避免锁表影响业务。
内容的提问来源于stack exchange,提问作者cauchuyennhocuatoi
相关产品推荐
相关产品推荐

