21

我不确定我是否正确理解稀疏索引。

我在 fbId 上有一个稀疏的唯一索引

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

我期待这将允许我插入带有 null 作为 fbId 的记录,但这会引发重复键异常。如果 fbId 属性被完全删除,它只允许我插入。

稀疏索引不应该处理吗?

4

3 回答 3

40

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

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

于 2011-12-22T19:02:00.687 回答
2

为了确保索引的最大性能,我们可能希望省略那些不包含您正在执行索引的字段的文档的索引。为此,MongoDB 具有 sparse 属性,其工作方式如下:

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

该索引将省略所有不包含 secondAddress 字段的文档,并且在执行查询时,这些文档将永远不会被扫描。

让我分享这篇关于基本索引及其一些属性的文章:

地理空间、文本、哈希索引以及唯一和稀疏属性: http: //mongodbspain.com/en/2014/02/03/mongodb-indexes-part-2-geospatial-2d-2dsphere/

于 2014-02-10T00:26:59.460 回答
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索引,数据库也会执行所有文档扫描,尤其是在进行排序时。这可以在's 结果 的获胜计划部分中看到。explain

于 2016-09-03T17:34:41.813 回答