MongoDB隐式与显式AND运算符行为异常问题排查
MongoDB查询中隐式AND替代显式AND后结果偏差原因
需求说明
统计sample_training.companies数据集中满足以下任一条件的公司数量:
- 2004年成立,且
category_code为social或web - 10月成立,且
category_code为social或web
三种查询方案
1. verbose写法(正确结果:149)
db.companies.find({ $or: [ {$and: [{ "founded_year": 2004 }, { $or: [{ "category_code": "social" }, { "category_code": "web" }] }] }, {$and: [{ "founded_month": 10 }, { $or: [{ "category_code": "social" }, { "category_code": "web" }] }] } ] }).count()
2. 逻辑等价简化写法(正确结果:149)
db.companies.find({ $and: [ {$or: [{"category_code":"social"}, {"category_code":"web"}]}, {$or: [{"founded_year":2004}, {"founded_month": 10}]} ] }).count()
3. 尝试隐式AND的写法(错误结果:668)
db.companies.find({ $or: [{"category_code":"social"}, {"category_code":"web"}], $or: [{"founded_year":2004}, {"founded_month": 10}] }).count()
结果偏差原因
MongoDB的查询条件本质是JSON对象,而JSON语法不允许同一个对象中存在重复的键。当你在查询文档中写了两个$or键时,后面的$or会直接覆盖前面的$or条件。
也就是说,第三种查询实际上只执行了{$or: [{"founded_year":2004}, {"founded_month": 10}]}这一个条件,完全忽略了关于category_code的过滤,所以统计出的是所有2004年成立或10月成立的公司总数,自然和正确结果偏差极大。
内容的提问来源于stack exchange,提问作者Manu Torres
相关产品推荐
相关产品推荐

