多餐厅外卖订单:计算司机对应各餐厅订单总额的最优方案
问题
我开发了一款多餐厅外卖订单应用,订单以文档形式存储在Firestore中,每个订单文档包含以下字段:
total: double deliveredByUid: str restaurantId: str
我希望能在当日任意时段查看每位司机对应各餐厅的订单总额,格式示例如下:
robert: mcdonalds: 10 kfc: 20 alex: mcdonalds: 35 kfc: 10
我目前有几种思路,想知道计算所有订单总额的最优方法:
- 安全简易但成本较高的方法:每次需要获取总额时,查询当日所有文档并逐个计算;
- Cloud Functions方案:每当订单新增/删除时,修改Realtime database中特定节点
/totals/<driverId>/<placeId>的值; - 手动统计方案:每当司机完成订单并将其ID写入订单对象时,额外向Realtime database对应节点写入数据。
编辑说明:补充了完整的订单对象。
最优方案分析
方案1:实时查询计算
优势:实现简单,无需额外维护统计数据,数据绝对准确,无同步偏差问题。
劣势:成本高——当日订单量越大,单次查询的Firestore读取次数越多,费用会随订单量增长快速上升;订单量上千时,查询计算的延迟会明显影响用户体验。
适用场景:单日订单量几十单以内的初期阶段,或仅偶尔需要查看统计的场景。
方案2:Cloud Functions自动同步
优势:
- 数据自动同步,无需业务代码额外处理,开发成本低;
- 统计数据实时更新,查询时直接读取
/totals/<driverId>/<placeId>即可,速度快、读取成本极低; - 可覆盖订单新增、删除、金额修改等所有变更场景,只要监听Firestore订单事件就能自动处理。
劣势:初期需要配置部署Cloud Functions,有一定调试成本;高并发场景下需注意函数幂等性,避免重复统计。
适用场景:订单量中等及以上、需要实时查看统计数据的生产环境,这是最优的平衡方案。
方案3:手动统计写入
优势:无需依赖Cloud Functions,业务代码直接控制统计逻辑,调试相对直观。
劣势:
- 业务代码耦合度高,订单的新增、删除、修改等所有操作都要同步处理统计节点写入,容易遗漏场景;
- 易出现数据不一致,比如订单写入成功但统计节点写入失败,需额外做事务处理保证一致性,开发复杂度高。
适用场景:不愿使用Cloud Functions且订单流程极单一(仅新增无修改/删除)的场景,不推荐长期使用。
最终推荐
优先选择方案2(Cloud Functions自动同步),它在数据准确性、维护成本、查询性能之间达成了最佳平衡。若初期订单量极小,可先用方案1过渡,后续再切换到方案2。
内容的提问来源于stack exchange,提问作者George O
相关产品推荐
相关产品推荐

