MongoDB查询时如何忽略文本任意位置的双中括号匹配目标内容
解决方案
方案一:聚合表达式查询(适配MongoDB 4.4+,无额外权限要求,性能远优于$where)
直接在find查询中使用聚合操作符清洗字段后匹配,不需要修改数据结构:
如果你需要完全匹配(清洗后内容和查询字符串完全相等),使用如下语句:
db.collection.find({ $expr: { $eq: [ // 两次替换移除所有[[和]] { $replaceAll: { input: { $replaceAll: { input: "$key", find: "[[", replacement: "" } }, find: "]]", replacement: "" } }, "should be matched" ] } })
如果你需要包含匹配(清洗后内容包含查询字符串即可,和你之前写的includes逻辑一致),使用如下语句:
db.collection.find({ $expr: { $ne: [ { $indexOfCP: [ { $replaceAll: { input: { $replaceAll: { input: "$key", find: "[[", replacement: "" } }, find: "]]", replacement: "" } }, "should be matched" ] }, -1 ] } })
方案二:正则匹配(适配所有MongoDB版本,不需要聚合支持)
你可以构造特殊正则,匹配时自动忽略字符串中任意位置的[[、]]标记:
// 先把查询字符串转义后插入可忽略[[/]]的匹配规则 const target = "should be matched"; const regexStr = target.split("").map(c => c.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')).join("(?:\\[\\[|\\]\\])*"); db.collection.find({ key: { $regex: regexStr, $options: "i" } // 不需要大小写敏感就去掉i参数 })
最优长期方案(查询频繁时推荐)
如果这类查询是高频操作,建议新增预处理字段key_clean,写入数据时就提前移除key中的[[、]]后存入该字段,给key_clean建立索引后直接查询:
// 精确匹配直接走索引,性能最高 db.collection.find({ key_clean: "should be matched" }) // 前缀包含匹配也可以走索引,性能远高于实时计算 db.collection.find({ key_clean: /^should be matched/ })
内容的提问来源于stack exchange,提问作者G M
相关产品推荐
相关产品推荐

