Różnica między ustawieniem z {merge: true} a aktualizacją

115

W Cloud Firestore są trzy operacje zapisu:

1) dodaj

2) zestaw

3) aktualizacja

W dokumentach jest napisane, że używanie set(object, {merge: true}) spowoduje scalenie obiektu z istniejącym.

To samo dzieje się, gdy używasz update(object) Więc jaka jest różnica, jeśli w ogóle? Wydaje się dziwne, że Google powiela logikę.

ZuzEL
źródło

Odpowiedzi:

264

Sposób, w jaki zrozumiałem różnicę:

  • setbez mergespowoduje nadpisanie dokumentu lub utworzenie go, jeśli jeszcze nie istnieje

  • setwith mergezaktualizuje pola w dokumencie lub utworzy go, jeśli nie istnieje

  • update zaktualizuje pola, ale zakończy się niepowodzeniem, jeśli dokument nie istnieje

  • create utworzy dokument, ale zakończy się niepowodzeniem, jeśli dokument już istnieje

Istnieje również różnica w rodzaju danych, które udostępniasz setiupdate .

Na setzawsze trzeba dostarczyć dane dokumentu w kształcie:

set(
  {a: {b: {c: true}}},
  {merge: true}
)

Za pomocą updatemożesz również użyć ścieżek pól do aktualizacji zagnieżdżonych wartości:

update({
  'a.b.c': true
})
Scarygami
źródło
1
ale gdzie znalazłeś createmetodę w API?
ZuzEL
2
cloud.google.com/nodejs/docs/reference/firestore/0.8.x/… dla node.js. Wygląda na to, że internetowy interfejs API nie ma tej metody. Nie byłem pewien, na której platformie jesteś :)
Scarygami
10
Inną różnicą, o której możesz wspomnieć, jest to, że setoperuje na danych w kształcie dokumentu, gdzie updateprzyjmuje pary ścieżki pola i wartości. Oznacza to, że możesz wprowadzać zmiany w głęboko zagnieżdżonych wartościach, updatektóre są bardziej uciążliwe set. Na przykład: set({a: {b: {c: true}}}, {merge: true})vs update('a.b.c', true).
Gil Gilbert
Jeśli chcę zaktualizować wartość w dokumencie, ma sens, że chcę zaktualizować dokumenty, które już istnieją, więc myślę, że set + mergeall nie jest przydatny, ponieważ utworzy go, dokument nie istnieje
John Balvin Arias
Jeśli dane, które podajesz do polecenia set, mają pole o wartości null, czy ustawi to pole na wartość null, jeśli jest już obecne w bazie danych, czy też pozostawi je w spokoju?
user1023110
71

Inna różnica (rozszerzenie odpowiedzi Scarygamiego) między "ustaw z scalaniem" i "aktualizacją" dotyczy pracy z zagnieżdżonymi wartościami.

jeśli masz dokument o takiej strukturze:

 {
   "friends": {
     "friend-uid-1": true,
     "friend-uid-2": true,
   }
 }

i chcesz dodać {"friend-uid-3" : true}

używając tego:

db.collection('users').doc('random-id').set({ "friends": { "friend-uid-3": true } },{merge:true})

spowoduje, że dane te:

 {
   "friends": {
     "friend-uid-1": true,
     "friend-uid-2": true,
     "friend-uid-3": true
   }
 }

jednak updateużywając tego:

db.collection('users').doc('random-id').update({ "friends": { "friend-uid-3": true } })

spowoduje, że dane te:

 `{
   "friends": {
     "friend-uid-3": true
   }
 }`
Finlay Percy
źródło
1
Czy próbowałeś to samodzielnie przetestować? W dokumentacji znajduje się sekcja: "Aby zaktualizować niektóre pola dokumentu bez nadpisywania całego dokumentu, użyj metody update () ..." link
Finlay Percy
2
Rozgryzłem to. Wcześniej próbowałem tego tylko z tablicą. Gdzie chciałem dodać obiekt do tablicy i wszystko zostało nadpisane dla tej tablicy. Nie działa z polami zawierającymi tablicę ... nie działa z dokumentami.
ravo10
1
Po testach doszedłem do tego samego wniosku. Mam nadzieję, że dodadzą opcję, która daje taki sam efekt jak { merge: true }funkcja aktualizacji.
Johnride,
1
Dzięki za tę odpowiedź! Przykłady, choć proste, sprawiły, że było to bardziej przejrzyste niż przyjęta odpowiedź, która z nich była lepsza w moim przypadku.
naiveai
2
Aby uniknąć nadpisywania danych w zagnieżdżonych polach (jak w powyższej odpowiedzi) podczas używania update, możesz użyć notacji kropkowej . Zachowanie nadpisywania updatejest inne, jeśli używasz / nie używasz notacji kropkowej.
Tedskovsky
7

Na dokumenty: https://firebase.google.com/docs/firestore/manage-data/add-data#update_fields_in_nested_objects

Notacja z kropką umożliwia aktualizację pojedynczego pola zagnieżdżonego bez nadpisywania innego pola zagnieżdżonego. Jeśli zaktualizujesz zagnieżdżone pole bez notacji kropkowej, nadpiszesz całe pole mapy.

Jak wspomniano powyżej, zastępuje to całą strukturę znajomych.

db.collection('users').doc('random-id').update({
    "friends": {
        "friend-uid-3": true
    }
})

Tak nie jest.

db.collection('users').doc('random-id').update({
    "friends.friend-uid-3": true
})
CodeManDan
źródło