MongoDB中$where递归正则深度查询未返回匹配结果问题排查
问题根因
你的查询返回0条结果是4个核心逻辑错误导致的:
- 正则匹配逻辑完全错误:代码里
if (obj[field] == new_value)是拿字段的字符串值直接和RegExp正则对象做相等比较,二者数据类型不同,这个判断永远不会返回true,自然匹配不到任何记录。 - 正则重复构造逻辑错误:递归调用时你把已经生成的RegExp对象作为
value参数传入,又执行new RegExp("^"+value, "i")做二次构造,会把正则对象转为格式错误的正则规则,完全偏离预期;且额外加的^开头锚点会导致嵌套字段里的内容无法被匹配。 - 正则语法不严谨:匹配规则里的
.是正则通配符(匹配任意单个字符),你要匹配IP里的字面.需要转义为\.,否则会出现误匹配。 - 递归逻辑缺边界判断:JS里
typeof null的返回值也是object,遍历到null值时会进入递归逻辑触发报错,直接终止当前文档的匹配流程。
修正后的可运行查询
db.collection.find( { $where: function() { function deepIterate(obj, regex) { // 处理基础类型值,直接做正则匹配 if (!obj || typeof obj !== 'object') { return regex.test(obj); } for (var field in obj) { const currentVal = obj[field]; if (typeof currentVal !== 'object') { // 基础类型直接校验匹配结果 if (regex.test(currentVal)) { return true; } } else { // 嵌套对象、数组递归遍历 if (deepIterate(currentVal, regex)) { return true; } } } return false; } // 正则仅初始化一次,转义字面量点,移除不必要的开头锚点 const targetRegex = /[A-Za-z0-9.]*60\.51[A-Za-z0-9.]*/i; return deepIterate(this, targetRegex); } } )
额外提示
$where查询需要把所有BSON文档转为JS对象后逐行遍历执行,性能极低,不要在生产环境的大集合上使用,建议针对需要检索的字段提前建立文本索引,或者把嵌套字段扁平化存储后做普通正则查询,性能会提升几个数量级。
内容的提问来源于stack exchange,提问作者roguepanda
相关产品推荐
相关产品推荐

