MongoDB 4.4使用$replaceAll结合正则替换字段文本失效问题
问题背景
我需要替换集合字段中冗余的文本内容,现有测试数据如下:
_id:12345678901, name:"Company Z" _id:12345678902, name: "Corp Y" _id:12345678902, name: "Corporation X"
需求为移除name字段中的Corp、Corporation、Company文本,将处理结果存入新增的newName字段,原name字段保留,预期处理结果如下:
_id:12345678901, name: "Company Z", newName: "Z" _id:12345678902, name: "Corp Y", newName: "Y" _id:12345678902, name: "Corporation X", newName: "X"
当前使用的是mongod 4.4.14版本,最初编写了如下updateMany聚合更新语句,尝试结合$replaceAll与$regexFind通过正则匹配实现替换,但语句执行后未达到预期效果:
db.customers.updateMany( { }, [{ $set: { newName: { $replaceAll: { input: "$name", find: {"$regexFind": { input: "$name", regex: '/(Corp)|(Corporation)|(Company)/gi' } }, replacement: "" } }} }] )
原语句错误原因
$replaceAll的find参数仅接受字符串类型输入,$regexFind返回的是包含匹配内容、匹配位置、捕获组的结构化对象,不是纯字符串,无法作为替换目标传入- 正则写法不符合MongoDB聚合语法规范:正则参数不需要额外加
/包裹符,忽略大小写等标志需要单独放在options字段中,不能直接拼接在正则字符串末尾 - 逻辑存在缺陷:
$regexFind仅会返回第一个匹配项的结果,无法覆盖多个匹配值的场景,且替换后未处理残留的空格
4.4版本兼容的正确实现
MongoDB 4.4版本的$replaceAll不支持正则作为匹配规则,直接嵌套调用$replaceAll依次替换三个目标字符串,最后用$trim清理前后空格即可,性能比正则方案更稳定:
db.customers.updateMany( {}, [ { $set: { newName: { $trim: { input: { $replaceAll: { input: { $replaceAll: { input: { $replaceAll: { input: "$name", find: "Company", replacement: "" } }, find: "Corporation", replacement: "" } }, find: "Corp", replacement: "" } } } } } } ] )
注意:替换顺序要优先替换
Company、Corporation这类长字符串,最后替换短字符串Corp,避免短字符串提前匹配把长字符串截断导致替换不全。
执行后即可得到符合预期的newName字段结果,原name字段不会被修改。
内容的提问来源于stack exchange,提问作者Gr4y
相关产品推荐
相关产品推荐

