2011-12-22 134 views
17

我不确定我是否正确理解稀疏索引。mongo中的稀疏索引和空值

我有一个稀疏唯一索引FBID

{ 
    "ns" : "mydb.users", 
    "key" : { 
     "fbId" : 1 
    }, 
    "name" : "fbId_1", 
    "unique" : true, 
    "sparse" : true, 
    "background" : false, 
    "v" : 0 
} 

而且我期待,让我插入记录用null作为FBID,而是抛出一个重复键异常。它只允许我插入fbId属性被完全删除。

是不是一个稀疏的索引应该处理?

回答

31

稀疏索引不包含缺少索引字段的文档。但是,如果字段存在并且值为null,它仍将被索引。因此,如果该字段的缺失及其与null的等同性对于您的应用程序而言看起来相同,并且您希望保持fbId的唯一性,那么只有在您为其获取值之前不要插入它。

当您拥有大量文档时,您需要稀疏索引,但只有一小部分文档包含某个字段,并且您希望能够通过该字段快速查找文档。创建一个普通的索引会太贵,你只需要浪费宝贵的RAM来索引你不感兴趣的文档。

1

为了确保索引的最大性能,我们可能希望省略索引那些不包含字段的文档您正在执行索引。要做到这一点的MongoDB有稀疏的属性,工作原理如下:

db.addresses.ensureIndex({ "secondAddress": 1 }, { sparse: true }); 

该指数将省略所有不包含secondAddress领域和执行查询时,这些文件将永远不会被扫描的文档。

让我分享这篇文章基本指标和它们的一些性质:

地理空间信息,文字,散列索引和独特的和稀疏的属性:http://mongodbspain.com/en/2014/02/03/mongodb-indexes-part-2-geospatial-2d-2dsphere/

1

{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的结果部分。