我对MongoDB稀疏索引有点怀疑。我有一个收藏(帖子),里面只有很少的文档(最大的6K),可以用这种方式嵌入子文档:
{
"a": "a-val",
"b": "b-val",
"meta": {
"urls": [ "url1", "url2" ... ],
"field1": "value1",
...
}
}
字段"a"one_answers"b"始终存在,但"meta.uls"可能不存在!
现在,我只插入了一个具有"meta.uls"值的文档,然后我进行了
db.post.ensureIndex({"a": 1, "b": 1, "meta.urls": 1}, {sparse: true});
帖子统计数据给了我一个"奇怪"的结果:索引大约是97MB!这怎么可能?只有一个文档插入了"meta.urls",并且索引大小为97MB?
因此,我尝试以这种方式只创建"meta.uls"索引:
db.post.ensureIndex({"meta.urls": 1}, {sparse: true});
我现在只有一个文档的"meta.uls_1"索引。但如果我解释一个像这样的简单查询
db.post.find({"meta.urls": {$exists: true}}).hint("meta.urls_1").explain({verbose: true});
我有另一个"奇怪"的结果:
"n" : 1,
"nscannedObjects" : 5,
"nscanned" : 5,
为什么Mongo扫描5个文档,而不仅仅是索引中的文档?
如果我在"meta.uls"上查询精确匹配,那么单个稀疏索引将正常工作。
示例:db.post.find({"meta.uls":"url1"}).inmit("meta.old_slugs_1")//1文档
对于您的第一个问题:您可以使用复合索引来搜索它索引的键的前缀。例如,如果只搜索a
或同时搜索a
和b
,则会使用第一个索引。因此,sparse
只会在a
为空的情况下对文档进行索引。
我没有第二个问题的答案,但你应该尝试更新MongoDB,然后再试一次——它移动得很快,稀疏索引在过去几个月里变得更好了。