如何在React+Chart.js项目中按月份动态查询Firestore疫苗接种数据
Firestore按月动态查询实现方案
你的Firestore用户数据结构参考:
首先确认你存储的接种日期为Firestore原生Timestamp类型(如为字符串格式建议统一转换为Timestamp,避免范围查询异常),以下为两种可行实现方案:
方案1:时间范围查询(无需修改现有数据结构)
适用于临时需求、不想改动现有数据写入逻辑的场景,核心逻辑是计算目标月份的时间边界,用范围查询匹配数据:
- 先根据用户选择的
selectedYear(年份)、selectedMonth(月份),计算出当月第一天的零点和下一个月第一天的零点作为查询边界 - 给现有查询追加时间范围过滤条件
- 首次查询如果触发索引缺失报错,点击报错信息中的索引创建链接,一键创建对应复合索引即可正常使用
示例代码:
// 注意JavaScript中月份从0开始计数,用户选择的1月对应0,需要做转换 const startOfTargetMonth = new Date(selectedYear, selectedMonth - 1, 1); const startOfNextMonth = new Date(selectedYear, selectedMonth, 1); // 拼接完整查询,假设首剂接种日期字段为doses.firstDoseDate const vaccineQuery = db.collection("users") .where("doses.selectedVaccine", "==", selectedVaccine) .where("doses.firstDose", "==", true) .where("doses.firstDoseDate", ">=", startOfTargetMonth) .where("doses.firstDoseDate", "<", startOfNextMonth); // 执行查询获取结果 const querySnapshot = await vaccineQuery.get(); const targetRecords = querySnapshot.docs.map(item => item.data());
方案2:冗余年月字段优化(适合高频统计场景)
如果你的业务需要频繁做按月维度的统计,推荐在写入用户接种数据时,额外冗余存储一个doses.firstDoseYearMonth字段,格式为YYYY-MM字符串(例:2024-05)。这种方案直接用等值查询即可匹配目标月份数据,不需要处理时间边界,查询性能更高。
示例查询代码:
// 拼接为YYYY-MM格式,月份不足两位补0 const targetYearMonth = `${selectedYear}-${String(selectedMonth).padStart(2, '0')}`; const vaccineQuery = db.collection("users") .where("doses.selectedVaccine", "==", selectedVaccine) .where("doses.firstDose", "==", true) .where("doses.firstDoseYearMonth", "==", targetYearMonth);
React + Chart.js 对接提示
你可以把查询逻辑封装在useEffect钩子中,依赖selectedVaccine、selectedYear、selectedMonth三个变量,每次用户修改选择器时自动触发重新查询,统计完月度接种数据后更新Chart.js的数据集即可渲染可视化图表。如果需要展示全年12个月的趋势数据,可以批量查询12个月份的数据,统计后按月份排序即可。
内容的提问来源于stack exchange,提问作者JS3
相关产品推荐
相关产品推荐

