2016-07-13 40 views
2

我对NoSQL数据库完全陌生,目前我正在使用MongoDB。MongoDB - 为什么_id索引不会在重复条目上抛出错误?

我试图理解为什么默认_id索引不会抛出错误,当upserting a duplicate _id文件。

如文档指出_id是默认

的唯一索引(尽管它并不在这里展现出独特的标志。)

> db.foo.getIndexes(); 
[ 
    { 
     "v" : 1, 
     "key" : { 
      "_id" : 1 
     }, 
     "name" : "_id_", 
     "ns" : "test.foo" 
    } 
] 
> 

所以当upserting文档(始于一个空集合),
如果首先插入它,然后似乎“忽略”它。

> db.foo.update({ _id: 'doe123'}, { _id: 'doe123', name: 'John Doe'}, { upsert: true}); 
WriteResult({ "nMatched" : 0, "nUpserted" : 1, "nModified" : 0, "_id" : "doe123" }) 

> db.foo.update({ _id: 'doe123'}, { _id: 'doe123', name: 'John Doe'}, { upsert: true}); 
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 0 }) 

所以我尝试另一件事和“名”创建unique index

upserting重复名称的结果:

> db.foo.update({ _id: 'foo456'}, { _id: 'foo456', name: 'John Doe'}, { upsert: true}); 
WriteResult({ 
    "nMatched" : 0, 
    "nUpserted" : 0, 
    "nModified" : 0, 
    "writeError" : { 
     "code" : 11000, 
     "errmsg" : "E11000 duplicate key error collection: test.foo index: name_1 dup key: { : \"John Doe\" }" 
    } 
}) 

为什么我让这种错误的重复_id


编辑:我使用MongoDB的v.3.2.3

回答

1

没有理由表明在第一种情况下重复的索引错误,因为它只是试图更新_idname领域具有相同值的相同记录。

如果你会尝试

db.foo.update({ _id: '1098'}, { _id: 'doe123', name: 'John Doe'}, { upsert: true}); 

你会得到错误,如查询试图与一些现有的_id值更新与不同_id记录。

在第二种情况下,首先用name字段创建了一条记录,然后您试图在另一条记录中更新相同的名称,这会给出错误,因为name是唯一索引。

编辑: -

如果你想

db.foo.insert({ _id: 'doe123', name: 'John Doe'}); 

会给你的错误,因为在这种情况下,你想插入一条记录中已经存在即_id是独一无二的,你是试图用同样的_id值创建一个更多的记录。

upsert:true: - 如果upsert为true且没有文档匹配查询条件,则update()插入单个文档。

如果upsert为true并且存在符合查询条件的文档,update()将执行更新。

+0

我尝试了一些东西,我得到的异常/错误我期望使用** insert **而不是** upsert **:'“E11000重复键错误集合:test.foo索引:_id_ dup键:{:\“doe123 \”}“'。那么为什么插入会抛出错误,但upsert不会呢?仅仅因为它抬头*“我需要更新什么吗?不是吗?比我什么都不做”*? – Krenor

+1

'upsert:true'意味着它将插入,如果字段不存在,否则它只会更新值。在插入的情况下,它会尝试插入记录,该记录实际上具有“_id”的重复值。我希望现在很清楚。 – Shrabanee

+0

我已经更新了我的答案。 – Shrabanee

相关问题