Diferencia entre establecer con {merge: true} y actualizar

115

En Cloud Firestore hay tres operaciones de escritura:

1) agregar

2) establecer

3) actualización

En los documentos dice que el uso set(object, {merge: true})fusionará el objeto con uno existente.

Lo mismo sucede cuando usas update(object) Entonces, ¿cuál es la diferencia, si la hay? Parece extraño que Google duplique la lógica.

ZuzEL
fuente

Respuestas:

263

La forma en que entendí la diferencia:

  • setsin mergesobrescribirá un documento o lo creará si aún no existe

  • setcon mergeactualizará los campos en el documento o lo creará si no existe

  • update actualizará los campos pero fallará si el documento no existe

  • create creará el documento pero fallará si el documento ya existe

También hay una diferencia en el tipo de datos que proporciona a sety update.

Porque setsiempre debe proporcionar datos en forma de documento:

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

Con updatetambién puede utilizar rutas de campo para actualizar valores anidados:

update({
  'a.b.c': true
})
Scarygami
fuente
1
pero ¿dónde ha encontrado el createmétodo en la API?
ZuzEL
2
cloud.google.com/nodejs/docs/reference/firestore/0.8.x/… para node.js. Parece que la API web no tiene ese método. No estaba seguro en qué plataforma estás :)
Scarygami
10
Otra distinción que puede mencionar es que setopera sobre datos en forma de documento, donde updatetoma la ruta de campo y los pares de valores. Esto significa que puede realizar cambios en valores profundamente anidados updateque son más engorrosos set. Por ejemplo: set({a: {b: {c: true}}}, {merge: true})vs update('a.b.c', true).
Gil Gilbert
Si quiero actualizar un valor en un documento, tiene sentido que quiera actualizar documentos que ya existen, así que creo que set + mergeall no es tan útil porque lo creará, el documento no existe
John Balvin Arias
Si los datos que proporciona al comando set tienen un campo que es nulo, ¿establecerá el campo en nulo si ya está presente en la base de datos o lo dejará solo?
user1023110
71

Otra diferencia (extendiendo la respuesta de Scarygami) entre "establecer con fusión" y "actualizar", es cuando se trabaja con valores anidados.

si tiene un documento estructurado así:

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

y quiero agregar {"friend-uid-3" : true}

usando esto:

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

resultará en estos datos:

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

sin embargo updateusando esto:

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

resultará en estos datos:

 `{
   "friends": {
     "friend-uid-3": true
   }
 }`
Finlay Percy
fuente
1
¿Ha intentado probar esto usted mismo? Hay una sección en la documentación: "Para actualizar algunos campos de un documento sin sobrescribir todo el documento, use el método update () ..." enlace
Finlay Percy
2
Me lo imaginé. Solo probé esto con una matriz antes. Donde quería agregar un objeto a la matriz, y todo se sobrescribió para esa matriz. No funciona con campos que contienen una matriz ... sí lo soporta.
ravo10
1
Llegué a la misma conclusión después de las pruebas. Espero que agreguen una opción que tenga el mismo efecto { merge: true }que la función de actualización.
Johnride
1
¡Gracias por esta respuesta! Los ejemplos, aunque simples, lo hicieron más claro que la respuesta aceptada, cuál era mejor para mi caso de uso.
Naiveai
2
Para evitar sobrescribir datos en campos anidados (como en la respuesta anterior) al usar update, puede usar la notación de puntos . El comportamiento de sobrescritura de updatees diferente si usa o no la notación de puntos.
Tedskovsky
7

Por documentos: https://firebase.google.com/docs/firestore/manage-data/add-data#update_fields_in_nested_objects

La notación de puntos le permite actualizar un solo campo anidado sin sobrescribir otro campo anidado. Si actualiza un campo anidado sin notación de puntos, sobrescribirá todo el campo del mapa.

Como se indicó anteriormente, esto reemplaza toda la estructura de amigos.

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

Esto no lo hace.

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