Différence entre set with {merge: true} et update

115

Dans Cloud Firestore, il existe trois opérations d'écriture:

1) ajouter

2) ensemble

3) mise à jour

Dans la documentation, il est dit que l'utilisation set(object, {merge: true})fusionnera l'objet avec celui existant.

La même chose se produit lorsque vous utilisez update(object) Alors quelle est la différence, le cas échéant? Il semble étrange que Google duplique la logique.

ZuzEL
la source

Réponses:

264

La façon dont j'ai compris la différence:

  • setsans mergeécrasera un document ou le créera s'il n'existe pas encore

  • setavec mergemettra à jour les champs du document ou le créera s'il n'existe pas

  • update mettra à jour les champs mais échouera si le document n'existe pas

  • create créera le document mais échouera si le document existe déjà

Il y a aussi une différence dans le type de données que vous fournissez à setet update.

Car setvous devez toujours fournir des données sous forme de document:

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

Avec, updatevous pouvez également utiliser des chemins de champ pour mettre à jour les valeurs imbriquées:

update({
  'a.b.c': true
})
Scarygami
la source
1
mais où avez-vous trouvé la createméthode dans l'API?
ZuzEL
2
cloud.google.com/nodejs/docs/reference/firestore/0.8.x/… pour node.js. Il semble que l'API Web ne dispose pas de cette méthode. Je ne savais pas sur quelle plate-forme vous vous trouviez :)
Scarygami
10
Une autre distinction que vous pouvez mentionner est qu'elle setfonctionne sur des données en forme de document, où updateprend le chemin de champ et les paires de valeurs. Cela signifie que vous pouvez apporter des modifications aux valeurs profondément imbriquées avec updatequi sont plus lourdes avec set. Par exemple: set({a: {b: {c: true}}}, {merge: true})vs update('a.b.c', true).
Gil Gilbert
Si je veux mettre à jour une valeur dans un document, il est logique que je veuille mettre à jour des documents qui existent déjà, donc je pense que set + mergeall n'est pas si utile car cela créera le document n'existe pas
John Balvin Arias
Si les données que vous fournissez à la commande set ont un champ qui est nul, le définira-t-il sur null s'il est déjà présent dans la base de données ou le laissera-t-il seul?
user1023110
71

Une autre différence (étendant la réponse de Scarygami) entre "set with merge" et "update", est lorsque vous travaillez avec des valeurs imbriquées.

si vous avez un document structuré comme ceci:

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

et je veux ajouter {"friend-uid-3" : true}

en utilisant ceci:

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

se traduira par ces données:

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

cependant en updateutilisant ceci:

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

se traduira par ces données:

 `{
   "friends": {
     "friend-uid-3": true
   }
 }`
Finlay Percy
la source
1
Avez-vous essayé de tester cela vous-même? Il y a une section dans la documentation: "Pour mettre à jour certains champs d'un document sans écraser tout le document, utilisez la méthode update () ..." lien
Finlay Percy
2
Je l'ai compris. Je n'ai essayé cela qu'avec un tableau avant. Où je voulais ajouter un objet au tableau, et tout a été écrasé pour ce tableau. Cela ne fonctionne pas avec les champs contenant un tableau ... il résiste à la documentation.
ravo10
1
Je viens juste d'arriver à la même conclusion après les tests. J'espère qu'ils ajouteront une option qui aura le même effet que { merge: true }la fonction de mise à jour.
Johnride
1
Merci pour cette réponse! Les exemples, bien que simples, l'ont rendu plus clair que la réponse acceptée, laquelle était la meilleure pour mon cas d'utilisation.
naiveai
2
Pour éviter d'écraser les données dans les champs imbriqués (comme dans la réponse ci-dessus) lors de l'utilisation update, vous pouvez utiliser la notation par points . Le comportement d'écrasement de updateest différent si vous utilisez / n'utilisez pas la notation par points.
Tedskovsky
7

Par documents: https://firebase.google.com/docs/firestore/manage-data/add-data#update_fields_in_nested_objects

La notation par points vous permet de mettre à jour un seul champ imbriqué sans écraser un autre champ imbriqué. Si vous mettez à jour un champ imbriqué sans notation par points, vous écraserez tout le champ de la carte.

Comme indiqué ci-dessus, cela remplace toute la structure d'amis.

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

Ce n'est pas le cas.

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