我有大约8000万个文档的集合,每个文档都在tags现场存储一系列标记,例如:
{text: "blah blah blah...", tags: ["car", "auto", "automobile"]}
Run Code Online (Sandbox Code Playgroud)
该字段tags已编入索引,因此像这样的查询几乎是即时的:
db.documents.find({tags:"car"})
Run Code Online (Sandbox Code Playgroud)
但是,以下查询都非常慢,需要几分钟才能完成:
db.documents.find({tags:{$all:["car","phone"]}})
db.documents.find({tags:{$in:["car","auto"]}})
Run Code Online (Sandbox Code Playgroud)
即使阵列只有一个项目,问题仍然存在:
db.documents.find({tags:{$all:["car"]}}) //very slow too
Run Code Online (Sandbox Code Playgroud)
我认为$ all和$ in应该能够非常快速地工作,因为它tags被编入索引,但显然事实并非如此.为什么?
ram*_*ami 10
事实证明这是MongoDB中的已知错误,从2.2开始尚未修复
使用时,MongoDB 在搜索多个条目时不执行索引交集$all.仅使用索引查找阵列中的第一个项目,并执行所有匹配文档的扫描以过滤结果.
例如,在查询db.documents.find({tags:{$all:["car","phone"]}})中,需要检索和扫描包含标签"car"的所有文档.由于该收集包含超过十万个标有"汽车"的文件,因此放慢速度并不令人惊讶.
更糟糕的是,MongoDB甚至不执行在$ all数组中为索引查找选择表示最少的项目的简单优化.如果有100000个标记为"car"的文档和10个标记为"phone"的文档,MongoDB仍需要扫描100000个文档以返回结果{$all:["car", "phone"]}
另见:https://jira.mongodb.org/browse/SERVER-1000