В чем разница между сохранением и вставкой в ​​БД Mongo?

149

В чем разница между сохранением и вставкой в ​​БД Mongo? оба выглядят одинаково

db.users.save({username:"google",password:"google123"})

db.users.insert({username:"google",password:"google123"})
user2093576
источник
1
fyi save () теперь не рекомендуется в pymongo.
Гавриил Фэйр

Ответы:

147

Сохранить против вставки:

В приведенных вами примерах поведение, по сути, одинаково.

save ведет себя по-разному, если он передается с параметром "_id".

Для сохранения, если документ содержит _id, он будет отправлять запрос коллекции на _idполе, если нет, он будет вставлен.

Если документ с указанным значением _id не существует, метод save () выполняет вставку с указанными полями в документе.

Если документ существует с указанным значением _id, метод save () выполняет обновление, заменяя все поля в существующей записи полями из документа.


Сохранить и обновить :

updateизменяет существующий документ, соответствующий параметрам вашего запроса. Если такого документа нет, вот тогда и upsertпоявится изображение.

  • upsert : false : Ничего не происходит, когда такого документа не существует
  • upsert : true : Создается новый документ с содержанием, равным параметрам запроса и параметрам обновления

save: Не допускает никаких параметров запроса. если _idсуществует и есть соответствующий документ с тем же _id, он заменяет его. Когда _id не указан / не соответствует документу, он вставляет документ как новый.

Рахул
источник
8
оба имеют разный синтаксис. Обновление принимает несколько аргументов ({условие}, {обновление до документа}, upsert, multi), тогда как сохранение принимает только один аргумент (_id является параметром для условного аргумента). Update может принимать любое условие, но сохранение имеет ограничение условия только для поле _id.
Рахул
1
Начиная с версии 2.6, save имеет второй аргумент, принимающий документ, выражающий озабоченность записи. docs.mongodb.org/manual/reference/method/db.collection.save
Huggie
79

Давайте рассмотрим два случая здесь для сохранения:

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:       
squiroid
источник
10
Диаграммы следующего уровня
Джон Спитери
2
Проголосовал за время, затрачиваемое на аккуратную прорисовку и представление диаграмм.
Фанбонди
36

save вставить или обновить документ.

insert делает только вставку.

Но в вашем случае это будет сделано так же, так как в документе, указанном в save, нет _idполя.

Аурелиен Б
источник
13

Приведя пример

Сохранить яблоко

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"
}

Таким образом, сохранение будет действовать как обновление, если оно предоставлено с идентификатором объекта, при условии, что идентификатор объекта уже существует, иначе он выполняет вставку.

Аби
источник
10

Если вы попытаетесь использовать «вставить» с идентификатором, который ранее использовался в той же коллекции, вы получите ошибку дублированного ключа. Если вы используете «сохранить» с идентификатором, который уже находится в той же коллекции, он будет обновлен / перезаписан.

Если вы хотите сделать настоящее обновление, я бы предложил использовать «обновление». Обновление не будет перезаписано, как при сохранении, если вы сохраняете с использованием того же идентификатора, который уже есть в коллекции.

Например, у вас есть два поля «x» и «y», и вы хотите оставить оба поля, но измените значение «x». Если вы выбрали команду «сохранить» и не включили y с предыдущим значением или у вас не было y в вашем сохранении, то y больше не будет иметь такое же значение или будет там. Однако, если вы выбрали обновление с использованием $ set и в вашем выражении обновления был указан только x, вы не затронули бы y.

RoganRicheart
источник
3

Рассмотрим документ ниже

{ "_id" : 1, "domainName" : "test1.com", "hosting" : "hostgator.com" }

если БД уже содержит документ с _id: 1, то

операция сохранения вызовет исключение, как показано ниже

E11000 duplicate key error index ...........

и где, как операция вставки, просто переопределит документ.

Браво
источник
db.collection.save()Метод обновляет документ, если документ с таким же _id уже существует в базе данных. Когда документ с таким же _id уже существует в базе данных, метод save полностью заменяет документ новым документом. Из книги - Pro MongoDB Development
пустой бланк
1

В терминах ORACLE: вставка монго => вставка Oracle, сохранение монго => объединение Oracle

Джагана
источник
1

db.<collection_name>.save(<Document>) эквивалентно InsertOrUpdate Query.

Хотя, db.<collection_name>.insert(<Document>)это эквивалентно просто вставить запрос.

Вийет Бадиганнавар
источник