Jaka jest różnica między zapisywaniem a wstawianiem w Mongo DB?

148

Jaka jest różnica między zapisywaniem a wstawianiem w Mongo DB? oba wyglądają tak samo

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

db.users.insert({username:"google",password:"google123"})
user2093576
źródło
1
fyi save () jest teraz przestarzała w pymongo.
Gabriel Fair

Odpowiedzi:

146

Zapisz Vs Insert:

W podanych przykładach zachowanie jest zasadniczo takie samo.

save zachowuje się inaczej, jeśli zostanie przekazany z parametrem „_id”.

Do zapisania, jeśli dokument zawiera _id, wyśle ​​zapytanie o kolekcję w _idpolu, jeśli nie, wstawi.

Jeśli dokument nie istnieje o określonej wartości _id, metoda save () wykonuje wstawienie z określonymi polami w dokumencie.

Jeśli istnieje dokument o określonej wartości _id, metoda save () przeprowadza aktualizację, zastępując wszystkie pola w istniejącym rekordzie polami z dokumentu.


Zapisz a aktualizacja :

updatemodyfikuje istniejący dokument dopasowany do parametrów zapytania. Jeśli nie ma takiego pasującego dokumentu, to upsertpojawia się na zdjęciu.

  • upsert : false : Nic się nie dzieje, gdy taki dokument nie istnieje
  • upsert : true : Nowy dokument zostanie utworzony z zawartością równą parametrom zapytania i parametrom aktualizacji

save: Nie zezwala na żadne parametry zapytań. jeśli _idistnieje i jest zgodny dokument z tym samym _id, zastępuje go. Gdy nie określono _id / brak pasującego dokumentu, wstawia dokument jako nowy.

Rahul
źródło
8
oba mają inną składnię. Update przyjmuje wiele argumentów ({condition}, {update to doc}, upsert, multi), podczas gdy save akceptuje tylko jeden argument (_id jest parametrem dla argumentu warunkowego). Update może akceptować dowolny warunek, ale save ma ograniczenie warunku tylko na pole _id.
Rahul
1
Od wersji 2.6 funkcja save ma drugi argument dotyczący dokumentu wyrażającego problem z zapisem. docs.mongodb.org/manual/reference/method/db.collection.save
huggie
77

Rozważmy tutaj dwa przypadki dla uratowania: -

1) Posiadanie _id w dok.

2) Brak identyfikatora _id w dok.

                        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.

Rozważmy tutaj dwa przypadki dla wstawienia: -

1) Posiadanie _id dokumentu w kolekcji.

2) Brak identyfikatora _id dokumentu w kolekcji.

                        Insert()
                       /        \
                      /          \

   Doc Having _id in collection    Doc Not Having _id 
  ->  E11000 duplicate key     ->Insert a new doc inside the collection.
      error index:       
squiroid
źródło
10
Diagramy kolejnych poziomów
John Spiteri
2
Głosowano za czas potrzebny na staranne narysowanie i zaprezentowanie diagramów.
fanbondi
36

save wstawić lub zaktualizować dokument.

insert wykonuje tylko wstawianie.

Ale w twoim przypadku zrobi to samo, ponieważ dokument dostarczony w zapisie nie ma _idpola.

Aurélien B
źródło
13

Podając przykład

Uratuj jabłko

db.fruit.save({"name":"apple", "color":"red","shape":"round"})
WriteResult({ "nInserted" : 1 })

db.fruit.find();

{
    "_id" : ObjectId("53fa1809132c1f084b005cd0"),
    "color" : "red",
    "shape" : "round",
    "name" : "apple"
}

Zapisz jabłko z _id poprzednio zapisanego jabłka

db.fruit.save(
{"_id" : ObjectId("53fa1809132c1f084b005cd0"),"name":"apple", 
"color":"real red","shape":"round"})

WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

Teraz zachowane jabłko zmieniło kolor z czerwonego na prawdziwy czerwony

db.fruit.find();
{
    "_id" : ObjectId("53fa1809132c1f084b005cd0"),
    "color" : "real red",
    "shape" : "round",
    "name" : "apple"
}

Zapisz jabłko za pomocą _id

db.fruit.save({"_id" : ObjectId("55551809132c1f084b005cd0"),
"name":"apple", "color":"real red","shape":"round"})

    WriteResult({ "nMatched" : 0, "nUpserted" : 1, 
"nModified" : 0, "_id": 55551809132c1f084b005cd0 })

Apple zostało wstawione, ponieważ nie ma jabłka z tym samym identyfikatorem obiektu, aby wykonać aktualizację

Wstaw Orange

db.fruit.insert({"name":"orange", "color":"orange","shape":"round"})
WriteResult({ "nInserted" : 1 })

Pomarańczowy jest wstawiony

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

Tak więc save będzie działał jako aktualizacja, jeśli zostanie dostarczony z identyfikatorem obiektu, pod warunkiem, że identyfikator obiektu już istnieje, w przeciwnym razie dokona wstawienia.

Abhi
źródło
10

Jeśli spróbujesz użyć polecenia „wstaw” z identyfikatorem, który był wcześniej używany w tej samej kolekcji, zostanie wyświetlony zduplikowany błąd klucza. Jeśli użyjesz „zapisz” z identyfikatorem, który jest już w tej samej kolekcji, zostanie on zaktualizowany / nadpisany.

Jeśli chcesz zrobić prawdziwą aktualizację, sugerowałbym użycie opcji „aktualizacja”. Aktualizacja nie nadpisze w sposób, w jaki zrobiłby to Save, jeśli zapisujesz używając tego samego identyfikatora, który jest już w kolekcji.

Na przykład masz dwa pola „x” i „y” i chcesz zachować oba, ale zmienić wartość „x”. Jeśli wybrałeś komendę "zapisz" i nie włączyłeś y do poprzedniej wartości lub nie masz w ogóle y w swoim składowaniu, wtedy y nie miałby już tej samej wartości lub nie istniałby. Jeśli jednak zdecydujesz się aktualizować za pomocą $ set i masz tylko x uwzględnione w instrukcji aktualizacji, nie wpłyniesz na y.

RoganRicheart
źródło
3

Rozważ poniższy dokument

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

jeśli baza danych zawiera już dokument z _id: 1, to

operacja zapisu wyrzuci wyjątek jak poniżej

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

i gdzie jako operacja wstawiania, po prostu nadpisuje dokument.

Brawo
źródło
db.collection.save()metoda aktualizuje dokument, jeśli dokument o tym samym identyfikatorze _id już istnieje w bazie danych. Gdy dokument o tym samym identyfikatorze _id już istnieje w bazie danych, metoda zapisu całkowicie zastępuje dokument nowym dokumentem. Z książki - Pro MongoDB Development
jack blank
1

Jeśli chodzi o ORACLE: mongo insert => Oracle insert mongo save => Oracle merge

Jagan
źródło
1

db.<collection_name>.save(<Document>) jest równoważne kwerendzie InsertOrUpdate.

While, db.<collection_name>.insert(<Document>)jest odpowiednikiem samego Wstaw zapytanie.

Vijet Badigannavar
źródło