2016-07-13 56 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

相關問題