使用{merge:true}和更新设置之间的差异

时间:2017-10-06 02:17:40

标签: database firebase google-cloud-firestore

Cloud Firestore 中,有三种写操作:

1)添加

2)设置

3)更新

在文档中,它说使用set(object, {merge: true})会将对象与现有对象合并。

使用update(object)时会发生同样的情况 那么有什么区别呢?谷歌会复制逻辑似乎很奇怪。

5 个答案:

答案 0 :(得分:119)

我理解差异的方式:

    没有合并的
  • @foreach (var police in agent.IndividualPolices) { <tr class="collapse collapseone_@agent.Agjenti" id="collapseone_@agent.Agjenti" aria-expanded="true" > <td> <a asp-controller="Polisat" asp-action="Detail" asp-route-id="@police.PoliceId">@police.PoliceNo</a> </td> <td> @police.Klienti </td> <td> @police.Paketa </td> <td> @police.Valide </td> </tr> } 将覆盖文档或创建文档(如果它还不存在)

  • 带有合并的
  • set将更新文档中的字段,或者如果文档不存在则创建

  • set会更新字段,但如果文档不存在则会失败

  • update将创建文档但如果文档已存在则会失败

您提供给createset的数据类型也有所不同。

对于update,您始终必须提供文档形状的数据:

set

使用set( {a: {b: {c: true}}}, {merge: true} ) ,您还可以使用字段路径更新嵌套值:

update

答案 1 :(得分:39)

另一个区别(扩展Scarygami的答案)&#34;设置为merge&#34;和&#34;更新&#34;,是在使用嵌套值时。

如果您的文档结构如下:

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

并想添加{"friend-uid-3" : true}

使用:

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

将导致此数据:

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

然而update使用此:

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

将导致此数据:

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

答案 2 :(得分:0)

每个文档:https://firebase.google.com/docs/firestore/manage-data/add-data#update_fields_in_nested_objects

点表示法使您可以更新单个嵌套字段,而不会覆盖其他嵌套字段。如果更新不带点标记的嵌套字段,则将覆盖整个地图字段。

如上所述,这将替换整个朋友结构。

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

不是。

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

答案 3 :(得分:0)

另一个有趣的行为,可能有用但并不明显。

当您进行batch更新时,并且不想检查您尝试更新的所有文档是否都存在

使用batch update,如果至少一个文档不存在,您的请求将失败。

使用batch set {merge: true},您的请求将成功更新所有现有文档,并为不存在的ID创建虚拟文档。

可能的用例:当此API一起提供现有和已删除文档的数据时,将Google Analytics(分析)从analytics reporting api合并到您的文档中。

答案 4 :(得分:0)

进一步补充上述答案,如果您想要删除地图中的嵌套字段,那么您可能需要根据您的用例使用 updateset .

如果您从以下开始,并想删除除 "user1" 之外的所有个人资料条目,那么您有两个选择。

{
  "users": {
    "profiles": {
      "user1": ...,
      "user2": ...
    }
  }

更新

这将使用提供的任何内容覆盖 profiles

update({
  'users.profiles': { 'user1': ... }
})

设置

这会将删除的内容合并到现有的配置文件中, 留下任何未被删除的内容

set({
  users: {
    profiles: {
      'user2': FieldValue.delete(),
      'user3': FieldValue.delete(),
      ...
    }
  }
}, { merge: true })

这仅适用于 Map,因为除非您明确使用 array-specific operators such as arrayUnion,否则 setupdate 都会覆盖数组。