我有大约8000万个文档的集合,每个文档都在tags
字段中存储一系列标记,例如:
{text: "blah blah blah...", tags: ["car", "auto", "automobile"]}
字段tags
已编入索引,因此像这样的查询几乎是即时的:
db.documents.find({tags:"car"})
但是以下查询都很慢,需要几分钟才能完成:
db.documents.find({tags:{$all:["car","phone"]}})
db.documents.find({tags:{$in:["car","auto"]}})
即使数组只有一个项目,问题仍然存在:
db.documents.find({tags:{$all:["car"]}}) //very slow too
我认为$ all和$ in应该能够非常快速地工作,因为tags
被编入索引,但显然并非如此。为什么呢?
答案 0 :(得分:10)
事实证明这是MongoDB中的一个已知错误,从2.2开始尚未修复。
使用$all
搜索多个条目时,MongoDB 不执行索引交集。仅使用索引查找阵列中的第一个项目,并执行所有匹配文档的扫描以过滤结果。
例如,在查询db.documents.find({tags:{$all:["car","phone"]}})
中,需要检索和扫描包含标签“car”的所有文档。由于有问题的收藏包含超过十万个标有“汽车”的文件,因此减速并不令人惊讶。
更糟糕的是,MongoDB甚至不执行在$ all数组中为索引查找选择表示最少的项目的简单优化。如果有100000个标记为“car”的文档和10个标记为“phone”的文档,MongoDB仍需要扫描100000个文档以返回{$all:["car", "phone"]}
的结果
答案 1 :(得分:-1)
我只想补充一下,$ in很快。事实上,对于只有1个标准或关键字,$ in相当于$ all,但$ in是快速的,而$ all是慢的。
所以请使用$ in。