我不确定我是否正确理解稀疏索引。
我在fbId上有一个稀疏的唯一索引
{
"ns" : "mydb.users",
"key" : {
"fbId" : 1
},
"name" : "fbId_1",
"unique" : true,
"sparse" : true,
"background" : false,
"v" : 0
}
我希望这会允许我插入带有null的记录作为fbId,但是会抛出重复的键异常。它只允许我在完全删除fbId属性时插入。
是不是应该处理的稀疏索引?
答案 0 :(得分:34)
稀疏索引不包含错过索引字段的文档。但是,如果字段存在且值为null
,则仍会将其编入索引。因此,如果该字段的缺失及其与null
的相等性对于您的应用程序看起来相同,并且您希望保持fbId
的唯一性,则只有在您拥有它的值之后才能插入它。 / p>
当您拥有大量文档时,您需要稀疏索引,但只有一小部分文档包含某些字段,并且您希望能够通过该字段快速查找文档。创建一个普通的索引太贵了,你只会浪费宝贵的RAM来索引你不感兴趣的文档。
答案 1 :(得分:2)
{a:1, b:5, c:2}
{a:8, b:15, c:7}
{a:4, b:7}
{a:3, b:10}
假设我们希望在上述文档中创建索引。在a
&上创建索引b
不会成为问题。但是如果我们需要在c
上创建索引呢?唯一约束不适用于c
键,因为2个文档的空值重复。在这种情况下,解决方案是使用sparse
选项。此选项告诉数据库不包含错过密钥的文档。关注的命令是db.collectionName.createIndex({thing:1}, {unique:true, sparse:true})
。稀疏索引使我们也可以使用更少的空间。
请注意,即使我们有
sparse
索引,数据库也会执行所有文档扫描,特别是在进行排序时。这可以在explain
的结果的获胜计划部分中看到。
答案 2 :(得分:1)
为了确保索引的最大性能,我们可能希望省略索引那些不包含您正在执行索引的字段的文档。为此,MongoDB具有稀疏属性,其工作方式如下:
db.addresses.ensureIndex( { "secondAddress": 1 }, { sparse: true } );
此索引将省略所有不包含secondAddress字段的文档,并且在执行查询时,将永远不会扫描这些文档。
让我分享一下有关基本索引及其一些属性的文章:
地理空间,文本,哈希索引以及唯一和稀疏属性:http://mongodbspain.com/en/2014/02/03/mongodb-indexes-part-2-geospatial-2d-2dsphere/