MongoDB正则表达式查询失效问题排查及解决方案咨询
我注意到你在MongoDB 3.4.7版本里遇到了正则查询无结果的问题,其实这类问题在社区里挺常见的——比如之前有人提到过测试环境的bug导致正则失效,但绝大多数情况都是正则格式使用错误引发的。
你在本地Ubuntu通过apt安装的MongoDB 3.4.7里的测试情况很典型:
db.web_configs.find({key: 'cck'}).pretty();
这个精确匹配能正常返回结果,但下面两种写法都查不到数据:
db.web_configs.find({key: "/cck/"}).pretty();
db.web_configs.find({key: {$regex:"/cck/"}}).pretty();
问题根源
这两种写法的核心问题是把正则表达式当成字符串传入了:
- 第一种写法中,
"/cck/"是一个普通字符串,MongoDB会去匹配key值恰好等于"/cck/"的文档,而非将其作为正则表达式解析。 - 第二种写法虽然用了
$regex操作符,但传入的依然是带首尾斜杠的字符串"/cck/",MongoDB会把斜杠当作正则表达式的一部分去匹配,自然找不到对应的数据。
正确的写法
你后来找到的解决方法完全正确,这里再明确两种有效写法:
- 直接使用正则字面量(不需要加引号):
db.web_configs.find({key: /cck/}).pretty();
- 使用
$regex操作符时,传入正则字面量或不带首尾斜杠的字符串:
db.web_configs.find({key: {$regex:/cck/}}).pretty();
// 也可以写成纯字符串形式(去掉首尾斜杠):
db.web_configs.find({key: {$regex:"cck"}}).pretty();
额外提醒(Node.js场景)
在Node.js中调用MongoDB时也容易踩同样的坑:如果不小心把正则写成了字符串(比如"/cck/"),而不是传入RegExp对象(比如new RegExp('cck')或者直接使用/cck/),也会出现查询无结果的问题,需要特别注意。
内容的提问来源于stack exchange,提问作者goFrendiAsgard

