我收集了大约 30K 个项目,所有这些项目都有一个名为 Program 的元素。“程序”是复合索引的第一部分,因此查找具有特定程序值的项目非常快。运行范围查询也很快,例如:
db.MyCollection.find(
{ $and: [ { Program: { "$gte" : "K", "$lt" : "L" } },
{ Program: { "$gte" : "X", "$lt" : "Y" } } ] }).count();
上面的查询没有返回任何结果,因为我正在查询两个非重叠范围(KL)和(XY)的重叠)。左侧范围 (KL) 包含大约 7K 项。
但是,如果我用“where”表达式替换第二个“and”子句,查询执行需要很长时间:
db.MyCollection.find(
{ $and: [ { Program: { "$gte" : "K", "$lt" : "L" } }, { "$where" : "this.Program == \"Z\"" } ] }).count();
如您所见,上面的查询也应该返回一个空结果集(范围 KL 与 Program=="Z" 结合)。我知道“where”的性能很慢,但是 Mongo 不应该首先通过评估 left 子句(这将导致大约 7K 项)来减少潜在的结果集,然后才应用“where”检查?如果是这样,处理几千个项目是否应该像在我的机器上那样花费几秒钟而不是几分钟,而 Mongo 服务在执行此操作时消耗大约 3GB RAM?相对较小的收藏看起来太重了。