MongoDB - Почему индекс _id не выдает ошибку для дублированных записей?
Я совершенно новичок в базах данных NoSQL, и сейчас я работаю с MongoDB.
Я пытаюсь понять, почему по умолчанию _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
на "имя".
Результат сохранения дублирующего имени:
> 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 ответ
Нет причины показывать ошибку дублируемого индекса в первом случае, так как он просто пытается обновить _id
а также name
поля одной и той же записи с одинаковым значением.
Если вы попробуете
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() выполняет обновление.