Яка різниця між збереженням та вставкою в БД Mongo?


148

Яка різниця між збереженням та вставкою в БД Mongo? обидва виглядають однаково

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

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


1
fyi save () тепер застаріло в pymongo.
Ярмарок Габріеля

Відповіді:


146

Зберегти проти вставки:

У наведених прикладах поведінка по суті однакова.

save поводиться інакше, якщо він передається з параметром "_id".

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

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

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


Зберегти проти оновлення :

updateзмінює існуючий документ, сумісний із вашими парами запитів. Якщо такого відповідного документа немає, то це upsertз’являється на знімку.

  • upsert : false : Нічого не відбувається, коли такого документа не існує
  • upsert : true : Створюється новий документ із вмістом, рівним парамерам запитів та оновленням

save: Не дозволяє будь-які параметри запитів. якщо _idіснує і є збігається документ з тим самим _id, він замінює його. Якщо не вказано _id / немає відповідного документа, він вставляє документ як новий.


8
обидва мають різний синтаксис. Оновлення містить кілька аргументів ({умова}, {оновлення до doc}, upsert, multi), тоді як збереження приймає лише один аргумент (_id є параметром для умовного аргументу). Update може приймати будь-яку умову, але збереження має обмеження умови лише на _id поле.
Рахул

1
Починаючи з версії 2.6, у збереження є другий аргумент, який приймає документ, що виражає занепокоєння щодо запису. docs.mongodb.org/manual/reference/method/db.collection.save
huggie

77

Розглянемо два випадки для заощадження: -

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:       

10
Діаграми наступного рівня
Джон Шпітері

2
Запропонований час, який потрібно акуратно намалювати та представити діаграми.
фанбонді

36

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

insert робить лише вставку.

Але у вашому випадку це зробить так само, як і документ, що надається в збереженні, не має _idполя.


13

Наводячи приклад

Збережіть Apple

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

Apple вставив, оскільки немає яблука з тим самим Id Object, щоб зробити оновлення

Вставте апельсин

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

Якщо ви спробуєте використати "вставити" з ідентифікатором, який раніше використовувався в тій же колекції, ви отримаєте помилку дублюючого ключа. Якщо ви використовуєте "зберегти" з ідентифікатором, який вже знаходиться в одній колекції, він буде оновлений / перезаписаний.

Якщо ви хочете зробити справжнє оновлення, я б запропонував використовувати "оновлення". Оновлення не буде перезаписано способом Save, якщо ви зберігаєте, використовуючи той самий ідентифікатор, який вже є у колекції.

Наприклад, у вас є два поля "x" і "y", і ви хочете зберегти обидва, але змінити значення "x". Якщо ви вибрали команду "save" і не включили y з попереднім значенням або взагалі не мали y у вашому збереженні, то y більше не матиме того ж значення або не буде там. Однак якщо ви вирішили оновити за допомогою $ set і у вашій заяві оновлення було включено лише x, ви не вплинете на y.



3

Розглянемо документ нижче

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

якщо db вже містить документ з _id: 1, то

операція збереження викине виняток, як показано нижче

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

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


db.collection.save()метод оновлює документ, якщо документ із тим самим _id вже існує в базі даних. Коли документ із тим самим _id вже існує в базі даних, метод збереження повністю замінює документ новим документом. З книги - Pro MongoDB Development
джек-пусто


1

db.<collection_name>.save(<Document>) еквівалентно запиту InsertOrUpdate.

Хоча, db.<collection_name>.insert(<Document>)еквівалентно лише Вставити запит.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.