如何从MySQL查询结果生成嵌套对象?(Node.js/React场景)
问题描述
我通过Node.js从MySQL查询获取了如下模拟数据集:
id date (y/m/d) value 1 2022-1-1 random value 2 2022-2-5 random value 3 2022-3-3 random value 4 2022-4-6 random value 5 2022-5-11 random value 6 2022-6-7 random value 7 2022-7-16 random value 8 2022-8-4 random value 9 2022-9-7 random value 10 2022-10-8 random value 11 2022-11-4 random value 12 2022-12-9 random value 13 2023-1-2 random value 14 2023-2-4 random value 15 2023-3-22 random value 16 2023-4-5 random value 17 2023-5-8 random value 18 2023-6-19 random value 19 2023-7-12 random value 20 2023-8-4 random value 21 2023-9-2 random value 22 2023-10-10 random value 23 2023-11-21 random value 24 2023-12-27 random value
需要将其转换为如下按年、月、日层级嵌套的对象结构,用于React前端展示:
[{ year:2022, value:[ { month:1, value:[ { day:1, value:'random value' } ] }, { month:2, value:[ { day:5, value:'random value' } ], ... } ] },{ year:2023, value:[ ... ] }]
该操作会在服务器上多次执行,因此需要高效、低开销的实现方案,请问有什么解决思路?
高效实现思路
1. 哈希映射快速定位层级,一次遍历完成分组
用Map对象记录已创建的年份、月份节点,遍历原始数据时直接定位到对应层级插入,避免重复遍历结果数组查找,时间复杂度为O(n),是最高效的分组方式:
function transformData(rawData) { const yearMap = new Map(); const result = []; for (const item of rawData) { // 若数据库已拆分年/月/日,可直接使用对应字段,跳过字符串解析 const [year, month, day] = item.date.split('-').map(Number); const itemValue = item.value; // 处理年份节点 let yearNode = yearMap.get(year); if (!yearNode) { yearNode = { year, value: [] }; yearMap.set(year, yearNode); result.push(yearNode); } // 处理月份节点,在年份节点内维护临时Map let monthMap = yearNode._monthMap; if (!monthMap) { monthMap = new Map(); yearNode._monthMap = monthMap; } let monthNode = monthMap.get(month); if (!monthNode) { monthNode = { month, value: [] }; monthMap.set(month, monthNode); yearNode.value.push(monthNode); } // 插入当日数据 monthNode.value.push({ day, value: itemValue }); } // 清理临时存储的_monthMap字段 result.forEach(node => delete node._monthMap); return result; }
2. 数据库层面提前优化,降低后端处理成本
- 直接拆分日期字段:在MySQL查询中用内置函数提取年、月、日,返回数字类型,避免后端做字符串解析:
SELECT id, YEAR(date_column) AS year, MONTH(date_column) AS month, DAY(date_column) AS day, value FROM your_table ORDER BY date_column; - 按日期排序:查询时加上
ORDER BY,确保数据按时间顺序返回,分组后层级内的月份、日期自然有序,无需额外排序。
3. 优化内存与执行效率
- 避免在循环内创建重复对象或函数,保持逻辑极简;
- 数据量极大时,使用MySQL流式查询(如
mysql2库的stream()方法),边读数据边分组,避免一次性加载全量数据到内存。
4. 缓存复用结果(数据更新频率低时适用)
如果数据不是实时更新,可将转换后的嵌套对象缓存到内存或Redis中,相同请求直接返回缓存结果,彻底避免重复执行转换逻辑。
内容的提问来源于stack exchange,提问作者Bassel Turky
相关产品推荐
相关产品推荐

