Node.js操作MongoDB时$where查询返回所有记录的问题排查
问题说明
- 集合字段
myregex为BSONRegExp类型,存储正则表达式匹配规则 - MongoDB shell中执行如下查询可正常返回匹配
'a'的记录:
db.secondaryregextest.find(function() { return this.myregex.test('a'); } )
- 迁移到Node.js环境后,使用如下代码执行查询会返回集合内全部记录,无法得到预期匹配结果:
var MongoClient = require('mongodb').MongoClient; var url = "mongodb://localhost:27017/"; MongoClient.connect(url, function(err, db) { if (err) throw err; var dbo = db.db("Testing"); dbo.collection("secondaryregextest").find( { $where: function() { return this.myregex.test('a') } } ).toArray(function (err,result) { if (err) { console.log(err); } else { console.log(result); } }); });
故障原因
Node.js版MongoDB驱动对传入$where的函数类型参数序列化逻辑存在特殊处理:不会把函数源码原样发送到MongoDB服务端执行,序列化过程会破坏函数内对文档字段this.myregex的引用,导致服务端执行匹配逻辑时判断失效,最终返回全量集合数据。
修复方案
将$where的参数从函数对象改为字符串形式的JS代码,驱动会将字符串原样传递给MongoDB服务端,由服务端内置JS引擎执行匹配逻辑,修正后可正常运行的代码如下:
dbo.collection("secondaryregextest").find( { $where: 'function() { return this.myregex.test("a") }' } ).toArray(function (err,result) { if (err) { console.log(err); } else { console.log(result); } });
提示:
$where查询需要逐文档执行JS逻辑,查询性能远低于MongoDB原生查询算子,大数据量场景下谨慎使用。
内容的提问来源于stack exchange,提问作者user3128461
相关产品推荐
相关产品推荐

