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


EDIT: Я использую MongoDB v.3.2.3

ответ

1

Там нет причин, чтобы показать повторяющиеся ошибки индекса в первом случае, как это просто пытается обновить _id и name поля той же записи с тем же значением.

Если вы попробуете

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

вы получите сообщение об ошибке, поскольку запрос пытается обновить запись с различными _id с некоторым существующим _id значения.

Во втором случае вы создали запись сначала с полем name, а затем вы пытаетесь обновить одно и то же имя в другой записи, что даст ошибку, так как name - уникальный индекс.

Edit: -

Если вы пытаетесь

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

даст вам ошибку, так как в этом случае вы пытаетесь вставить запись, которая уже присутствует т.е. _id является уникальным, и вы пытаясь создать еще одну запись с таким же значением _id.

upsert:true: - если upsert истинно и ни один документ не соответствует критериям запроса, update() вставляет один документ.

Если upsert истинно и есть документы, соответствующие критериям запроса, update() выполняет обновление.

+0

Я пробовал некоторые вещи, и я получил исключение/ошибку, которые я ожидал, используя ** insert ** вместо ** upsert **: '" E11000 дублирование коллекции ошибок: test.foo index: _id_ dup key: {: \ "doe123 \"} "'. Так почему же вставка вызывает мне ошибку, но угасает? Просто потому, что он поднимает глаза * «Нужно ли что-то обновлять? Нет? Ну, чем я ничего не делаю» *? – Krenor

+1

'upsert: true' означает, что он будет вставляться, если поля нет, иначе он просто обновит значение. В случае 'insert' он попытается вставить запись, которая на самом деле имеет дублирующее значение для' _id'. Надеюсь, теперь это ясно. – Shrabanee

+0

Я также обновил свой ответ. – Shrabanee