216

Cloud Firestore中有三种写入操作:

1) 添加

2) 设置

3) 更新

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

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

4

5 回答 5

481

我理解差异的方式:

  • setwithoutmerge将覆盖文档或创建它(如果它尚不存在)

  • setwithmerge将更新文档中的字段,如果不存在则创建它

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

  • create将创建文档,但如果文档已存在则失败

您提供给set和的数据类型也有所不同update

因为set您始终必须提供文档形状的数据:

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

update您还可以使用字段路径来更新嵌套值:

update({
  'a.b.c': true
})
于 2017-10-06T07:35:11.000 回答
110

“使用合并设置”和“更新”之间的另一个区别(扩展 Scarygami 的答案)是在使用嵌套值时。

如果您的文档结构如下:

 {
   "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
   }
 }`
于 2017-11-29T13:38:42.633 回答
13

每个文档: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
})
于 2019-12-28T03:10:34.550 回答
2

进一步补充上面的答案,如果您想删除地图中的嵌套字段,那么您可能需要使用updateset取决于您的用例。

如果您从以下内容开始并想要删除除此之外的所有配置文件条目,"user1"那么您有两个选择。

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

更新

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

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

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

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

这仅适用于Maps 因为两者setupdate都会覆盖数组,除非您明确使用特定于数组的运算符,例如arrayUnion.

于 2021-03-05T23:35:15.440 回答
0

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

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

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

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

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

于 2020-10-09T11:05:04.497 回答