В чем разница между сохранением и вставкой в БД Mongo? оба выглядят одинаково
db.users.save({username:"google",password:"google123"})
db.users.insert({username:"google",password:"google123"})
В чем разница между сохранением и вставкой в БД Mongo? оба выглядят одинаково
db.users.save({username:"google",password:"google123"})
db.users.insert({username:"google",password:"google123"})
Ответы:
Сохранить против вставки:
В приведенных вами примерах поведение, по сути, одинаково.
save
ведет себя по-разному, если он передается с параметром "_id".
Для сохранения, если документ содержит _id
, он будет отправлять запрос коллекции на _id
поле, если нет, он будет вставлен.
Если документ с указанным значением _id не существует, метод save () выполняет вставку с указанными полями в документе.
Если документ существует с указанным значением _id, метод save () выполняет обновление, заменяя все поля в существующей записи полями из документа.
Сохранить и обновить :
update
изменяет существующий документ, соответствующий параметрам вашего запроса. Если такого документа нет, вот тогда и upsert
появится изображение.
upsert : false
: Ничего не происходит, когда такого документа не существуетupsert : true
: Создается новый документ с содержанием, равным параметрам запроса и параметрам обновленияsave
: Не допускает никаких параметров запроса. если _id
существует и есть соответствующий документ с тем же _id
, он заменяет его. Когда _id не указан / не соответствует документу, он вставляет документ как новый.
Давайте рассмотрим два случая здесь для сохранения:
1) Наличие _id в док.
2) Не имея _id в док.
Save ()
/ \
/ \
Having _id Not Having _id
->In this case save will do -> It will do normal insertion
upsert to insert.Now in this case as insert() do.
what that means, it means
take the document and replace
the complete document having same
_id.
Давайте рассмотрим два случая здесь для вставки:
1) Наличие _id документа в коллекции.
2) Отсутствие _id документа в коллекции.
Insert()
/ \
/ \
Doc Having _id in collection Doc Not Having _id
-> E11000 duplicate key ->Insert a new doc inside the collection.
error index:
save
вставить или обновить документ.
insert
делает только вставку.
Но в вашем случае это будет сделано так же, так как в документе, указанном в save, нет _id
поля.
Приведя пример
Сохранить яблоко
db.fruit.save({"name":"apple", "color":"red","shape":"round"})
WriteResult({ "nInserted" : 1 })
db.fruit.find();
{
"_id" : ObjectId("53fa1809132c1f084b005cd0"),
"color" : "red",
"shape" : "round",
"name" : "apple"
}
Сохранить яблоко с _id ранее сохраненного яблока
db.fruit.save(
{"_id" : ObjectId("53fa1809132c1f084b005cd0"),"name":"apple",
"color":"real red","shape":"round"})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
Теперь у яблока, которое мы сохранили, цвет обновлен с красного на настоящий красный
db.fruit.find();
{
"_id" : ObjectId("53fa1809132c1f084b005cd0"),
"color" : "real red",
"shape" : "round",
"name" : "apple"
}
Сохранить яблоко с _id
db.fruit.save({"_id" : ObjectId("55551809132c1f084b005cd0"),
"name":"apple", "color":"real red","shape":"round"})
WriteResult({ "nMatched" : 0, "nUpserted" : 1,
"nModified" : 0, "_id": 55551809132c1f084b005cd0 })
Яблоко вставлено, так как нет яблока с тем же Object Id, чтобы сделать обновление
Вставьте апельсин
db.fruit.insert({"name":"orange", "color":"orange","shape":"round"})
WriteResult({ "nInserted" : 1 })
Оранжевый вставлен
db.fruit.find();
{
"_id" : ObjectId("53fa1809132c1f084b005cd0"),
"color" : "real red",
"shape" : "round",
"name" : "apple"
}
{
"_id" : ObjectId("53fa196d132c1f084b005cd7"),
"color" : "orange",
"shape" : "round",
"name" : "orange"
}
{
"_id" : ObjectId("55551809132c1f084b005cd0"),
"color" : "real red",
"shape" : "round",
"name" : "apple"
}
Таким образом, сохранение будет действовать как обновление, если оно предоставлено с идентификатором объекта, при условии, что идентификатор объекта уже существует, иначе он выполняет вставку.
Если вы попытаетесь использовать «вставить» с идентификатором, который ранее использовался в той же коллекции, вы получите ошибку дублированного ключа. Если вы используете «сохранить» с идентификатором, который уже находится в той же коллекции, он будет обновлен / перезаписан.
Если вы хотите сделать настоящее обновление, я бы предложил использовать «обновление». Обновление не будет перезаписано, как при сохранении, если вы сохраняете с использованием того же идентификатора, который уже есть в коллекции.
Например, у вас есть два поля «x» и «y», и вы хотите оставить оба поля, но измените значение «x». Если вы выбрали команду «сохранить» и не включили y с предыдущим значением или у вас не было y в вашем сохранении, то y больше не будет иметь такое же значение или будет там. Однако, если вы выбрали обновление с использованием $ set и в вашем выражении обновления был указан только x, вы не затронули бы y.
Как вы можете видеть здесь, метод save, по сути, выполнит upsert (обновите, если он найдет документ, вставьте в противном случае):
http://docs.mongodb.org/manual/reference/method/db.collection.save/#db.collection.save
Вставка - это просто прямая вставка.
Рассмотрим документ ниже
{ "_id" : 1, "domainName" : "test1.com", "hosting" : "hostgator.com" }
если БД уже содержит документ с _id: 1, то
операция сохранения вызовет исключение, как показано ниже
E11000 duplicate key error index ...........
и где, как операция вставки, просто переопределит документ.
db.collection.save()
Метод обновляет документ, если документ с таким же _id уже существует в базе данных. Когда документ с таким же _id уже существует в базе данных, метод save полностью заменяет документ новым документом. Из книги - Pro MongoDB Development
db.<collection_name>.save(<Document>)
эквивалентно InsertOrUpdate Query.
Хотя, db.<collection_name>.insert(<Document>)
это эквивалентно просто вставить запрос.