在 Firebase 中增加所有内容价值的最有效方法
Most efficient way to increment a value of everything in Firebase
假设我有这样的条目:
而且我想为估算列表中的每个项目将 priority
字段递增 1。
我可以这样获取估算值:
var estimates = firebase.child('Estimates');
在那之后,我如何将每个估计优先级自动递增 1?
这是遍历所有项目并提高其优先级的一种方法:
var estimatesRef = firebase.child('Estimates');
estimatesRef.once('value', function(estimatesSnapshot) {
estimatesSnapshot.forEach(function(estimateSnapshot) {
estimateSnapshot.ref().update({
estimateSnapshot.val().priority + 1
});
});
});
它遍历 Estimates
的所有 children 并增加每个的优先级。
您也可以将调用合并为一个 update()
调用:
var estimatesRef = firebase.child('Estimates');
estimatesRef.once('value', function(estimatesSnapshot) {
var updates = {};
estimatesSnapshot.forEach(function(estimateSnapshot) {
updates[estimateSnapshot.key+'/priority'] = estimateSnapshot.val().priority + 1;
});
estimatesRef.update(updates);
});
性能将与第一个解决方案相似(Firebase 在处理多个请求时非常高效)。但在第二种情况下,它将向服务器发送一个命令,因此它要么失败要么完全成功。
仅适用于 FIRESTORE API,不适用于 FIREBASE
感谢最新的 Firestore 补丁(2019 年 3 月 13 日),您无需按照上面的其他答案进行操作。
Firestore 的 FieldValue class 现在托管一个 increment 方法,该方法自动更新 firestore 数据库中的数字文档字段。您可以将此 FieldValue 标记与 set
(合并选项为真)或 DocumentReference
对象的 update
方法一起使用。
用法如下(来自官方docs,仅此而已):
DocumentReference washingtonRef = db.collection("cities").document("DC");
// Atomically increment the population of the city by 50.
washingtonRef.update("population", FieldValue.increment(50));
如果您想知道,它可以从 firestore 的 18.2.0
版本获得。为了大家方便,Gradle依赖配置为implementation 'com.google.firebase:firebase-firestore:18.2.0'
Note: Increment operations are useful for implementing counters, but
keep in mind that you can update a single document only once per
second. If you need to update your counter above this rate, see the
Distributed counters page.
编辑 1:FieldValue.increment()
纯粹是 "server" 方面(发生在 firestore 中),因此您不需要将当前值暴露给客户。
编辑 2:在使用管理员 API 时,您可以使用 admin.firestore.FieldValue.increment(1)
实现相同的功能。感谢@Jabir Ishaq 自愿让我知道未记录的功能。 :)
EDIT 3:如果要increment/decrement的目标字段不是数字或不存在,则increment
方法设置值到当前值!这在您第一次创建文档时很有用。
假设我有这样的条目:
而且我想为估算列表中的每个项目将 priority
字段递增 1。
我可以这样获取估算值:
var estimates = firebase.child('Estimates');
在那之后,我如何将每个估计优先级自动递增 1?
这是遍历所有项目并提高其优先级的一种方法:
var estimatesRef = firebase.child('Estimates');
estimatesRef.once('value', function(estimatesSnapshot) {
estimatesSnapshot.forEach(function(estimateSnapshot) {
estimateSnapshot.ref().update({
estimateSnapshot.val().priority + 1
});
});
});
它遍历 Estimates
的所有 children 并增加每个的优先级。
您也可以将调用合并为一个 update()
调用:
var estimatesRef = firebase.child('Estimates');
estimatesRef.once('value', function(estimatesSnapshot) {
var updates = {};
estimatesSnapshot.forEach(function(estimateSnapshot) {
updates[estimateSnapshot.key+'/priority'] = estimateSnapshot.val().priority + 1;
});
estimatesRef.update(updates);
});
性能将与第一个解决方案相似(Firebase 在处理多个请求时非常高效)。但在第二种情况下,它将向服务器发送一个命令,因此它要么失败要么完全成功。
仅适用于 FIRESTORE API,不适用于 FIREBASE
感谢最新的 Firestore 补丁(2019 年 3 月 13 日),您无需按照上面的其他答案进行操作。
Firestore 的 FieldValue class 现在托管一个 increment 方法,该方法自动更新 firestore 数据库中的数字文档字段。您可以将此 FieldValue 标记与 set
(合并选项为真)或 DocumentReference
对象的 update
方法一起使用。
用法如下(来自官方docs,仅此而已):
DocumentReference washingtonRef = db.collection("cities").document("DC");
// Atomically increment the population of the city by 50.
washingtonRef.update("population", FieldValue.increment(50));
如果您想知道,它可以从 firestore 的 18.2.0
版本获得。为了大家方便,Gradle依赖配置为implementation 'com.google.firebase:firebase-firestore:18.2.0'
Note: Increment operations are useful for implementing counters, but keep in mind that you can update a single document only once per second. If you need to update your counter above this rate, see the Distributed counters page.
编辑 1:FieldValue.increment()
纯粹是 "server" 方面(发生在 firestore 中),因此您不需要将当前值暴露给客户。
编辑 2:在使用管理员 API 时,您可以使用 admin.firestore.FieldValue.increment(1)
实现相同的功能。感谢@Jabir Ishaq 自愿让我知道未记录的功能。 :)
EDIT 3:如果要increment/decrement的目标字段不是数字或不存在,则increment
方法设置值到当前值!这在您第一次创建文档时很有用。