【问题标题】:MongoDB can not create unique sparse index (duplicate key)MongoDB 无法创建唯一稀疏索引(重复键)
【发布时间】:2014-12-29 22:21:46
【问题描述】:

我想在两列上创建唯一索引,其中索引的第二部分应允许多个空值。但是:

db.model.ensureIndex({userId : 1, name : 1},{unique : true, sparse : true});

抛出重复键异常:E11000 重复键错误索引:devmongo.model.$userId_1_name_1 dup key: { : "-1", : null }。我认为由于 sparse=true 选项,索引应该允许这个星座?我怎样才能做到这一点?我使用 MongoDB 2.6.5

【问题讨论】:

    标签: mongodb


    【解决方案1】:

    在我的例子中,字段名称是区分大小写的。

    因此在{field1 : 1, field2 : 1} 上创建复合索引与{Field1 : 1, Field2 : 1} 不同

    【讨论】:

      【解决方案2】:

      如果存在 任何 字段,稀疏复合索引将为文档创建一个索引条目,并将索引中的任何字段的值设置为 null文档中不存在。换句话说:稀疏复合索引只会在文档中缺少所有的索引字段时跳过文档。

      从 v3.2 开始,partial indexes 可用于完成您想做的事情。你可以使用:

      db.model.ensureIndex({userId : 1, name : 1}, { partialFilterExpression: { name: { $exists: true },  unique: true });
      

      它只会索引具有name 字段的文档。

      注意: mongo 不能使用此索引来处理userId 的查询,因为它不会包含集合中的所有文档。此外,文档中的null 被认为是一个值和一个具有null 值的字段存在

      【讨论】:

        【解决方案3】:

        复合索引应该被视为一个整体,所以unique要求(userId, name)对在集合中必须是唯一的,而sparse表示如果两者都userId 和 name 在文档中遗漏,这是允许的。错误信息显示至少有两个文档的 (userId, name) 对是等价的(如果缺少某个字段,则该值可以视为 null)。

        【讨论】:

        • 嗯好的,所以我将所有userId:“-1”更新为null,但仍然无法创建索引:E11000重复键错误索引:devmongo.model.$userId_1_name_1 dup键: { : null, : null }
        • @KIC,如果您可以将值更新为 null,则意味着您可以删除该字段,对吗?只删除两个字段(userId 和 name)然后 sparse 起作用,这将告诉 unique 文档应该超出 unique 的约束。因此,如果您删除所有带有 will -1 的 userId 字段,请确保 name 字段不重复,因为如果一个字段存在,另一个丢失的字段将被视为 null。
        • 实际上 sparse 仅适用于不存在的字段。空字段计为现有字段。这很愚蠢,但我必须忍受它。看来我必须重构我的数据模型:-(
        猜你喜欢
        • 2013-06-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-02-15
        • 2018-01-22
        • 2021-06-22
        相关资源
        最近更新 更多