Differenza tra set with {merge: true} e update


115

In Cloud Firestore sono disponibili tre operazioni di scrittura:

1) aggiungi

2) impostare

3) aggiornamento

Nella documentazione si dice che l'utilizzo set(object, {merge: true})unirà l'oggetto con quello esistente.

Lo stesso accade quando si utilizza update(object) Quindi qual è la differenza se esiste? Sembra strano che Google duplichi la logica.

Risposte:


264

Il modo in cui ho capito la differenza:

  • setsenza mergesovrascriverà un documento o lo creerà se non esiste ancora

  • setcon mergeaggiornerà i campi nel documento o lo creerà se non esiste

  • update aggiornerà i campi ma fallirà se il documento non esiste

  • create creerà il documento ma fallirà se il documento esiste già

C'è anche una differenza nel tipo di dati forniti a sete update.

Perché setdevi sempre fornire dati a forma di documento:

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

Con updatepuoi anche utilizzare i percorsi dei campi per aggiornare i valori nidificati:

update({
  'a.b.c': true
})

1
ma dove hai trovato il createmetodo nell'API?
ZuzEL

2
cloud.google.com/nodejs/docs/reference/firestore/0.8.x/… per node.js. Sembra che l'API web non abbia questo metodo. Non ero sicuro su quale piattaforma ti
trovassi

10
Un'altra distinzione che puoi menzionare è che setopera su dati a forma di documento, dove updateprende il percorso del campo e le coppie di valori. Ciò significa che puoi apportare modifiche a valori nidificati profondamente con updateche sono più complicati set. Ad esempio: set({a: {b: {c: true}}}, {merge: true})vs update('a.b.c', true).
Gil Gilbert

Se voglio aggiornare un valore in un documento, ha senso che io voglia aggiornare i documenti che già esistono, quindi penso che set + mergeall non sia così utile perché lo creerà il documento non esiste
John Balvin Arias

Se i dati forniti al comando set hanno un campo che è nullo, imposterà il campo su nullo se è già presente nel database o lo lascerà da solo?
user1023110

71

Un'altra differenza (estendendo la risposta di Scarygami) tra "set with merge" e "update", è quando si lavora con valori annidati.

se hai un documento strutturato in questo modo:

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

e vuoi aggiungere {"friend-uid-3" : true}

usando questo:

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

si tradurrà in questi dati:

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

tuttavia updateusando questo:

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

si tradurrà in questi dati:

 `{
   "friends": {
     "friend-uid-3": true
   }
 }`

1
Hai provato a testarlo da solo? C'è una sezione nella documentazione: "Per aggiornare alcuni campi di un documento senza sovrascrivere l'intero documento, usa il metodo update () ..." link
Finlay Percy

2
L'avevo capito. L'ho provato solo con un array prima. Dove volevo aggiungere un oggetto all'array e tutto è stato sovrascritto per quell'array. Non funziona con i campi che contengono un array ... lo sopporta docs.
ravo10

1
Sono appena arrivato alla stessa conclusione dopo i test. Spero che aggiungano un'opzione che ha lo stesso effetto { merge: true }della funzione di aggiornamento.
Johnride

1
Grazie per questa risposta! Gli esempi, sebbene semplici, rendevano più chiara la risposta accettata quale fosse la migliore per il mio caso d'uso.
naiveai

2
Per evitare di sovrascrivere i dati nei campi nidificati (come nella risposta sopra) quando si utilizza update, è possibile utilizzare la notazione punto . Il comportamento di sovrascrittura di updateè diverso se usi / non usi la notazione punto.
Tedskovsky il

7

Per documenti: https://firebase.google.com/docs/firestore/manage-data/add-data#update_fields_in_nested_objects

La notazione del punto consente di aggiornare un singolo campo nidificato senza sovrascrivere altri campi nidificati. Se aggiorni un campo nidificato senza notazione con il punto, sovrascriverai l'intero campo della mappa.

Come affermato sopra, questo sostituisce l'intera struttura degli amici.

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

Questo non lo fa.

db.collection('users').doc('random-id').update({
    "friends.friend-uid-3": true
})
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.