MongoError:E11000唯一复合索引的重复键错误集合

时间:2017-11-06 10:52:12

标签: mongodb indexing compound-index

  

问题与unique compound索引有关,与其他只有unique索引的问题不同。我对索引也有sparse: true

我的收藏中包含以下索引

[
  {
    "v": 2,
    "key": {
      "_id": 1
    },
    "name": "_id_",
    "ns": "somedb.votes"
  },
  {
    "v": 2,
    "key": {
      "answerId": 1
    },
    "name": "answerId_1",
    "ns": "somedb.votes",
    "sparse": true,
    "background": true
  },
  {
    "v": 2,
    "key": {
      "questionId": 1
    },
    "name": "questionId_1",
    "ns": "somedb.votes",
    "sparse": true,
    "background": true
  },
  {
    "v": 2,
    "unique": true,
    "key": {
      "answerId": 1,
      "votedBy": 1
    },
    "name": "answerId_1_votedBy_1",
    "ns": "somedb.votes",
    "sparse": true,
    "background": true
  },
  {
    "v": 2,
    "unique": true,
    "key": {
      "questionId": 1,
      "votedBy": 1
    },
    "name": "questionId_1_votedBy_1",
    "ns": "somedb.votes",
    "sparse": true,
    "background": true
  }
]

我收集了

中的以下文件
{
  "_id": ObjectId("59fdd3ce915511329553dfaa"),
  "updatedAt": ISODate("2017-11-04T14:54:22.110Z"),
  "votedAt": ISODate("2017-11-04T14:50:54.681Z"),
  "questionId": ObjectId("59fc77e45a857465a90339cc"),
  "value": -1,
  "votedBy": ObjectId("59fc4274aa686d39abe5d58a"),
  "type": "QuestionVote",
  "__v": 0
}

现在,当我尝试执行以下

db.votes.insert({ questionId: ObjectId("59fc798d5a857465a90339cf"), value: -1, votedBy: ObjectId("59fc4274aa686d39abe5d58a"), type: 'QuestionVote', _id: ObjectId("5a003240bfd8194a02d0add8") })

我收到以下错误

E11000 duplicate key error collection: somedb.votes index: answerId_1_votedBy_1 dup key: { : null, : ObjectId('59fc4274aa686d39abe5d58a') }
WriteResult({
  "nInserted": 0,
  "writeError": {
    "code": 11000,
    "errmsg": "E11000 duplicate key error collection: somedb.votes index: answerId_1_votedBy_1 dup key: { : null, : ObjectId('59fc4274aa686d39abe5d58a') }"
  }
})

我不明白原因。 索引为sparsecompound。但错误只是因为存在相同的votedBy字段。

即。执行以下内容,

db.votes.insert({votedBy: ObjectId("59fc4274aa686d39abe5d58a")})

即使votedBy对象上没有明确的索引,我也会收到以下错误。

E11000 duplicate key error collection: somedb.votes index: answerId_1_votedBy_1 dup key: { : null, : ObjectId('59fc4274aa686d39abe5d58a') }
WriteResult({
  "nInserted": 0,
  "writeError": {
    "code": 11000,
    "errmsg": "E11000 duplicate key error collection: somedb.votes index: answerId_1_votedBy_1 dup key: { : null, : ObjectId('59fc4274aa686d39abe5d58a') }"
  }
})

参考:复合指数 - https://docs.mongodb.com/manual/core/index-compound/#compound-indexes

2 个答案:

答案 0 :(得分:2)

这可能是因为使用此方法从控制台检查了相同集合的旧索引:

db.votes.getIndexes()

然后放弃它们:

db.votes.dropIndexes()

在定义架构的应用程序中,您应该像这样索引复合索引:

<your_schema_name>.index({
  field1: 1,
  field2:1,
  etc...
},{
    unique: true,
    sparse: true  //N.B:(sparse:true) is not a must for the compound unique indexing to work
});

现在重新启动您的应用程序,最后一个最终所需的复合索引应该可以正常工作。

额外注意

我在创建唯一索引时发现并且数据库中已有违反此创建的记录,但它无法正常工作。

来自node.js:

从我的mongoose驱动程序调试器中,我可以看到驱动程序试图索引

Mongoose: <my_collection>.ensureIndex({ field1: 1, 'field2.xx.xxx': 1, field: 3 }, { unique: true, background: true })

并且我没有从节点收到任何错误但是当我使用getIndexes()方法从控制台检查时,我没有找到新的索引。

从控制台:

我尝试了EnsureIndex

db.<my_collection>.ensureIndex({ field1: 1, 'field2.xx.xxx': 1, field: 3 }, { unique: true, background: true })

我收到了违反此索引的记录错误

{
    "ok" : 0,
    "errmsg" : "E11000 duplicate key error collection: <db_name>.<collection_name> index: field1_xxx.xxxx.xxxx_1_filed2_1 dup key: { : \"xxx\", : \"xxxx\", : ObjectId('xxx') }",
    "code" : 11000
}

<强>结论

如果有任何记录违反了新的索引,那么唯一索引(复合或不复合)将无法工作,即使您丢弃所有索引并按我之前提到的那样重试reIndex。

答案 1 :(得分:0)

此错误的原因是。索引不存在于您试图在其中插入记录的集合中。因此,解决方案是-删除该集合,然后再次运行程序。

相关问题