在firestore中,我有带有字段,日期和样本计数的文档。
每周一次,我想按日期分组聚合统计数据,即所有的标本计数应该为所有相同的日期加起来。
由于历史原因,我想将其存储在统计集合中。
我不确定是否应该将结果存储在地图字段中或使用日期作为文件编号和标本计数作为值。
最重要的是要存储它,这样可以很容易地读取历史记录。
以日期作为文档id,以标本计数作为值。因此,对于今天(28-08-2021)添加的文档,您可以像这样添加
Future<void> storeAnalytics(dynamic data) async {
await FirebaseFirestore.instance.collection("analytics").doc(data['id']).set(
{'value': FieldValue.increment(data['value']), 'date': data['date']},
SetOptions(merge: true));
// I used fieldValue.increment incase you have multiple data for 1 day.
// SetOptions(merge: true), will prevent overwriting data if it already exists
// I added date to the document incase in the future you want to fetch
// between a particular date range (eg. data for the year 2021). Here you can
// just use a where query.
}
// call the above function like this
// you can create a function that returns date (without hypen or slash)
// from regular date and for use as doc id
await storeAnalytics({'id': '28082021', 'value': 'xxx', 'date': 'put in date'});
// In the future, if you want the data, you can call it like this
Future<dynamic> getAnalytics(DateTime start, DateTime end) async {
await FirebaseFirestore.instance
.collection('analytics/')
.orderBy('date', descending: true)
.where('date', isGreaterThanOrEqualTo: start)
.where('date', isLessThan: end).get();
}
在设备上这样做是没有意义的,而是创建一个云函数来处理这个。Javascript模板如下:
const functions = require("firebase-functions");
const admin = require("firebase-admin");
const db = admin.firestore();
exports.onCreate = functions.firestore
.document("/path-to-document/")
.onCreate((snap, context) => {
const value = snap.data();
const specimentCount = value.value;
const timestamp = value.date;
const date = timestampToDate(timestamp);
const id = timestampToDayId(timestamp);
return db.doc("analytics/" + id)
.set(
{ data: admin.firestore.FieldValue.increment(specimentCount), date },
{ merge: true },
);
});
// if your document can be updated and deleted, you can add a listeners for
// that.
/**
* Returns javascript date (YYYYMMDD) from firebase timestamp.
* @param {timestamp} timestamp The firebase timestamp.
* @return {Date} The javascript date.
*/
function timestampToDate(timestamp) {
const date = timestamp.toDate();
date.setHours(0);
date.setMilliseconds(0);
date.setMinutes(0);
date.setSeconds(0);
return date;
}
/**
* Returns full id from firebase timestamp.
* @param {timestamp} timestamp The firebase timestamp.
* @return {String} The id.
*/
function timestampToDayId(timestamp) {
const date = timestamp.toDate();
let day = date.getDate();
if (day < 10) day = "0" + day;
let month = date.getMonth() + 1;
if (month < 10) month = "0" + month;
return date.getFullYear() + "" + month + "" + day;
}
使用云函数的一个优点是,您可以使用firestore规则限制分析收集的写入。只允许读取(云功能不需要被授予firestore访问权限)。另一个好处是这个任务不会占用设备资源。