rap*_*dko 14 javascript firebase google-cloud-firestore
我正在使用 firestore 更新我的对象上的数组。我在文档中发现我可以执行数组联合和删除,这很棒,这是文档中给出的示例:
var washingtonRef = db.collection("cities").doc("DC");
// Atomically add a new region to the "regions" array field.
washingtonRef.update({
regions: firebase.firestore.FieldValue.arrayUnion("greater_virginia")
});
// Atomically remove a region from the "regions" array field.
washingtonRef.update({
regions: firebase.firestore.FieldValue.arrayRemove("east_coast")
});
Run Code Online (Sandbox Code Playgroud)
如您所见,对数据库有 2 个单独的查询,这使我的应用程序在数据库调用方面的成本增加了一倍,因此我想将它们组合在一个查询中,如下所示:
var washingtonRef = db.collection("cities").doc("DC");
washingtonRef.update({
regions: firebase.firestore.FieldValue.arrayUnion("greater_virginia"),
regions: firebase.firestore.FieldValue.arrayRemove("east_coast")
});
Run Code Online (Sandbox Code Playgroud)
不幸的是,这不起作用,只有最后一个命令被执行。
有没有办法让它发挥作用?
sam*_*man 22
您的组合指令不起作用的原因(除了语法错误)是因为 FieldValue 对象的定义方式。
假设您使用了以下对象:
const arrayUnion = firebase.firestore.FieldValue.arrayUnion("greater_virginia")
const arrayRemove = firebase.firestore.FieldValue.arrayRemove("east_coast")
Run Code Online (Sandbox Code Playgroud)
返回的对象是FieldValue类的实现,相当于
const arrayUnion = {
_method: "FieldValue.arrayUnion",
_elements: ["greater_virginia"]
}
const arrayRemove = {
_method: "FieldValue.arrayRemove",
_elements: ["east_coast"]
}
Run Code Online (Sandbox Code Playgroud)
然后,根据 的值_method,使用此代码序列化适当的字段转换指令并将其发送到 Firestore API。由于操作是根据 的值切换的,因此在单个指令上只能发生或_method之一。arrayUnionarrayRemove
arrayUnion 和 arrayRemove二者arrayUnion并arrayRemove可以采取多个参数,将每个所述内部_elements上面显示阵列。
因此,要同时将"value1"和添加"value2"到指定字段,您将使用:
firebase.firestore.FieldValue.arrayUnion("value1", "value2");
Run Code Online (Sandbox Code Playgroud)
要将一组项目同时添加到指定字段,您可以使用:
var addedElements = ["greater_virginia", "east_coast", "central"];
firebase.firestore.FieldValue.arrayUnion.apply(null, addedElements);
// or
firebase.firestore.FieldValue.arrayUnion(...addedElements);
Run Code Online (Sandbox Code Playgroud)
因此,您只剩下三个选项,按易用性和推荐排序:
使用批量写入将允许您将指令一起写入数据库,如果任一部分失败,则不会有任何更改。
firebase.firestore.FieldValue.arrayUnion("value1", "value2");
Run Code Online (Sandbox Code Playgroud)
注意:每个批量写入最多可包含 500 个操作。但是,每个转换指令(arrayUnion、arrayRemove、increment和serverTimestamp)在此限制中计为 2 个操作。这意味着您最多只能执行 250 个单独的转换作为批处理的一部分。
这种特殊的数据结构让人联想到实时数据库以及引入arrayUnion和arrayRemove操作之前。
一般前提是在将数组上传到数据库之前对其进行转换。
var addedElements = ["greater_virginia", "east_coast", "central"];
firebase.firestore.FieldValue.arrayUnion.apply(null, addedElements);
// or
firebase.firestore.FieldValue.arrayUnion(...addedElements);
Run Code Online (Sandbox Code Playgroud)
被反转并存储为
var washingtonRef = db.collection("cities").doc("DC");
var batch = db.batch();
batch.update(washingtonRef, {regions: firebase.firestore.FieldValue.arrayUnion("greater_virginia")});
batch.update(washingtonRef, {regions: firebase.firestore.FieldValue.arrayRemove("east_coast")});
batch.commit()
.then(() => console.log('Success!'))
.catch(err => console.error('Failed!', err));
Run Code Online (Sandbox Code Playgroud)
可以使用以下方法实现上述结果:
const originalArr = ["greater_virginia", "east_coast", "central"]
Run Code Online (Sandbox Code Playgroud)
并恢复正常使用
const keyedObjectOfArr = {
"greater_virginia": 1
"east_coast": 1,
"central": 1
}
Run Code Online (Sandbox Code Playgroud)
然后,当您想应用联合/删除时,您将使用以下内容:
const keyedObjectOfArr = originalArr.reduce((acc, v) => (acc[v] = 1, acc), {});
Run Code Online (Sandbox Code Playgroud)
虽然此方法是一种选择,但对于此用例来说是不切实际的,因此建议不要使用。这篇博文涵盖了 Firebase 实时数据库中的数组,但这些问题在涉及大规模单个文档的内容时也适用。
Firestore API 中可能有空间支持同时添加和删除数组条目,因为它们在序列化层分开。
interface FieldTransform {
fieldPath?: string;
setToServerValue?: FieldTransformSetToServerValue;
appendMissingElements?: ArrayValue;
removeAllFromArray?: ArrayValue;
increment?: Value;
}
Run Code Online (Sandbox Code Playgroud)
所以你也可以提交一个功能请求,看看会发生什么。
| 归档时间: |
|
| 查看次数: |
5758 次 |
| 最近记录: |