在 Cloud Firestore 中,有三种写操作:
1)添加
2)设置
3)更新
在文档中,它说使用set(object, {merge: true})
会将对象与现有对象合并。
使用update(object)
时会发生同样的情况
那么有什么区别呢?谷歌会复制逻辑似乎很奇怪。
答案 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
将创建文档但如果文档已存在则会失败
您提供给create
和set
的数据类型也有所不同。
对于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)
进一步补充上述答案,如果您想要删除地图中的嵌套字段,那么您可能需要根据您的用例使用 update
或 set
.
如果您从以下开始,并想删除除 "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
,否则 set
和 update
都会覆盖数组。