在mongoDB中索引数组/子对象会导致重复键错误

时间:2016-03-14 02:57:08

标签: mongodb indexing

我有一个集合,我将拥有这样的_children属性:

{
  _children: {
    videoTags: [ { id: '1', name: 'one'}, { id: '2', name: 'two'} ],
  },
  a: 10
}

由于我将搜索videoTags,因此我会创建一个索引:

> db.test4.createIndex({ "_children.videosTags.id" : 1 }, { "unique" : true } );
{
    "createdCollectionAutomatically" : false,
    "numIndexesBefore" : 1,
    "numIndexesAfter" : 2,
    "ok" : 1
}

麻烦的是,我无法再将任何添加到该表中,因为我遇到了重复的索引错误。以下是如何重现它:

  • 第1步:插入集合

db.test4.insert({a:20}) WriteResult({ "nInserted" : 1 })

  • 第2步:制作索引

db.test4.createIndex({ "_children.videosTags.id" : 1 }, { "unique" : true } ); { "createdCollectionAutomatically" : false, "numIndexesBefore" : 1, "numIndexesAfter" : 2, "ok" : 1 }

  • 第3步:尝试再次插入

db.test4.insert({a:30}) WriteResult({ "nInserted" : 0, "writeError" : { "code" : 11000, "errmsg" : "insertDocument :: caused by :: 11000 E11000 duplicate key error index: wonder_1.test4.$_children.videosTags.id_1 dup key: { : null }" } })

我认为这里的问题是已经一条未记录_children.videoTags.id的记录。

但是,我所期望的是如果 videoTags.id被指定的行为,它必须是唯一的。相反,空的被视为"采取"键。

我在做什么是愚蠢的错? 如果您没有将unique设置为true,这将有效,但我觉得我需要将其修复为真实......

1 个答案:

答案 0 :(得分:1)

可能有两个原因。

  1. 集合中可能存在具有相同_children.videosTags.id

  2. 的其他文档
  3. 很可能多个文档可能缺少_children.videosTags.id"或具有空值。

  4. 当您创建unique键时,null或空值会给您带来困难。解决方案是创建sparse索引,如果您的MongoDB版本是3.2+,则创建部分索引。有关部分索引,请参阅documentation