在Cloud Firestore中有三种写操作:

add () 设置() update ()

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

当你使用update(object)…那么有什么不同呢?谷歌会像这样复制功能,这似乎很奇怪。


我是这样理解的:

设置而不合并将覆盖文档或创建文档(如果它还不存在) 使用merge设置将更新文档中的字段,如果它不存在,则创建它 Update将更新字段,但如果文档不存在则会失败 Create将创建文档,但如果文档已经存在,则创建失败

在提供设置和更新的数据类型上也有区别。

对于set,你总是需要提供文档形状的数据:

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

使用update,你也可以使用字段路径来更新嵌套值:

update({
  'a.b.c': true
})

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

如果你的文档结构是这样的:

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

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

用这个:

db.collection(“用户”). doc(随机身份)这里({ “朋友”:{ “friend-uid-3”:真的 } },{合并:真})

将得到以下数据:

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

但是使用这个更新:

db.collection(“用户”). doc(随机身份).update ({ “朋友”:{ “friend-uid-3”:真的 } })

将得到以下数据:

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

用于docs: https://firebase.google.com/docs/firestore/manage-data/add-data#update_fields_in_nested_objects

点表示法允许您更新单个嵌套字段,而无需覆盖其他嵌套字段。如果更新一个没有点表示法的嵌套字段,则将覆盖整个map字段。

如上所述,这将取代整个好友结构。

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

但这不是。

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

关于批处理还有一个有趣的行为:

如果至少有一个文档不存在,则批量更新将失败。

批处理设置{merge: true}将成功更新所有现有文档,并为不存在的文档创建新文档。


进一步补充上述答案,如果您想删除映射中的嵌套字段,那么您可能需要使用update或set,这取决于您的用例。

如果您从以下开始,并希望删除除“user1”之外的所有配置文件条目,那么您有两个选项。

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

更新

这将使用所提供的内容覆盖概要文件

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

Set

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

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

这只适用于map,因为set和update都会覆盖数组,除非显式地使用特定于数组的操作符,比如arrayUnion。


Scarygami的答案也适用于firebase版本9。但是应该考虑一些小的改变:

使用setDoc而不是set。例如,不要使用db.collection('users').doc('random-id')。集({“admin”:真});使用setDoc (doc (db,“用户的随机身份),{“admin”:真}) 使用updateDoc而不是update。例如,不要使用db.collection('users').doc(random-id')。update({"age": 27}),使用await updateDoc(doc(db, 'users', 'random-id'), {"age": 27})