Diferença entre definir com {merge: true} e atualizar

115

No Cloud Firestore, existem três operações de gravação:

1) adicionar

2) definir

3) atualização

Nos documentos diz que usar set(object, {merge: true}) irá mesclar o objeto com o existente.

O mesmo acontece quando você usa update(object) Então, qual é a diferença, se houver? Parece estranho que o Google irá duplicar a lógica.

ZuzEL
fonte

Respostas:

264

A maneira como entendi a diferença:

  • setsem mergeirá sobrescrever um documento ou criá-lo se ainda não existir

  • setcom mergeirá atualizar os campos no documento ou criá-lo se não existir

  • update irá atualizar os campos, mas irá falhar se o documento não existir

  • create irácriar o documento mas falhará se o documento já existir

Também há uma diferença no tipo de dados que você fornece seteupdate .

Pois setvocê sempre tem que fornecer dados em formato de documento:

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

Com updatevocê também pode usar caminhos de campo para atualizar valores aninhados:

update({
  'a.b.c': true
})
Assustador
fonte
1
mas onde você encontrou createmétodo na API?
ZuzEL
2
cloud.google.com/nodejs/docs/reference/firestore/0.8.x/… para node.js. Parece que a API da web não tem esse método. Não tinha certeza de qual plataforma você está :)
Scarygami
10
Outra distinção que você pode mencionar é que setopera em dados em formato de documento, onde updateleva o caminho do campo e pares de valor. Isso significa que você pode fazer alterações em valores profundamente aninhados com os updateque são mais complicados set. Por exemplo: set({a: {b: {c: true}}}, {merge: true})vs update('a.b.c', true).
Gil Gilbert
Se eu quiser atualizar um valor em um documento, faz sentido que eu queira atualizar os documentos que já existem, então eu acho que set + mergeall não é tão útil porque irá criar o documento não existe
John Balvin Arias
Se os dados que você fornecer ao comando set tiverem um campo que é nulo, ele definirá o campo como nulo se já estiver presente no banco de dados ou irá deixá-lo sozinho?
user1023110
71

Outra diferença (estendendo a resposta de Scarygami) entre "definir com mesclagem" e "atualizar" é ao trabalhar com valores aninhados.

se você tiver um documento estruturado assim:

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

e quero adicionar {"friend-uid-3" : true}

usando isto:

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

resultará nestes dados:

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

no entanto, updateusando isto:

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

resultará nestes dados:

 `{
   "friends": {
     "friend-uid-3": true
   }
 }`
Finlay Percy
fonte
1
Você já tentou testar isso sozinho? Há uma seção na documentação: "Para atualizar alguns campos de um documento sem sobrescrever todo o documento, use o método update () ..." link
Finlay Percy
2
Eu descobri. Eu só tentei isso com um array antes. Onde eu queria adicionar um objeto ao array, e tudo foi sobrescrito para aquele array. Ele não funciona com campos contendo um array ... ele suporta docs.
ravo10
1
Acabei de chegar à mesma conclusão após os testes. Espero que eles adicionem uma opção que tenha o mesmo efeito que { merge: true }a função de atualização.
Johnride
1
Obrigado por esta resposta! Os exemplos, embora simples, tornaram-no mais claro do que a resposta aceita qual era o melhor para o meu caso de uso.
Naiveai de
2
Para evitar sobrescrever dados em campos aninhados (como na resposta acima) ao usar update, você pode usar a notação de ponto . O comportamento de substituição de updateé diferente se você usar / não usar a notação de ponto.
Tedskovsky
7

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

A notação de ponto permite que você atualize um único campo aninhado sem substituir outro campo aninhado. Se você atualizar um campo aninhado sem notação de ponto, você substituirá todo o campo do mapa.

Conforme declarado acima, isso substitui toda a estrutura de amigos.

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

Isso não funciona.

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