关于MongoDB处理统计图数据(按天,小时)
说明:本文基于nest.js,typescript语法,mongoose,moment
前言:在网上找了很长时间,最终总结了如下两种方法,仅供参考
需要导的包:
import * as moment from moment;
import { DateTime } from ts-luxon;
import { InjectModel } from @nestjs/mongoose;
第一种方法:正常循环
//近七天趋势分析 const water_rush_chart = []; for (let i = 0; i < 7; i++) { const count = await this.WaterRushModel.aggregate([ { $match: { create_time: { $gte: DateTime.local().plus({ day: -i }).startOf(day),//前i天的00:00 $lte: DateTime.local().plus({ day: -i }).endOf(day),//前i天的59:59秒 }, }, }, //分组 { $group: { _id: null, //根据什么分组 value: { $sum: $flow }, //求需要的字段值之和,$sum为求和,$flow为字段 dataDate: { $push: $dataDate }, }, }, ]); water_rush_chart.unshift({ x: DateTime.local() .plus({ day: -(i + 1) }) .toFormat(LL-dd), //转化为月-日 y: count[0] ? count[0].value.toFixed(2) : 0, s: 数量, }); }
第二种方法:通过分组将数据按照所需时间分组
//近24小时趋势图 const count1 = await this.studentModel.aggregate([ { $match: { created_at: { $gte: DateTime.local().plus({ hours: -24 }).startOf(hour), $lte: DateTime.local().plus({ hours: -1 }).endOf(hour), }, }, }, //分组 { $group: { _id: { $subtract: [ { $subtract: [$created_at, new Date(1970-01-01)] }, { $mod: [{ $subtract: [$created_at, new Date(1970-01-01)] }, 1000 * 60 * 60 /*聚合时间段,24小时*/], }, ], }, name: { $push: $pump_room_name }, score: { $avg: $score }, time: { $push: $created_at }, }, }, //排序 { $sort: { time: 1, }, }, ]); //数据库查到的数据先存入数组 const student_arr = []; count1.filter((item) => { //添加平均成绩 student_arr.unshift({ x: moment(item.time[0]).format(HH:00), y: item.score || 0, s: 平均成绩, }); }); //学生平均成绩趋势如(不包含当前小时) const studnet_chart = []; let num1 = 0; for (let i = 0; i < 24; i++) { //获取当前时间 const time = DateTime.local() .plus({ hour: -(i + 1) }) .startOf(hour) .toFormat(HH:00); //判断所处时间是否有数据 if (num1 < student_arr.length && student_arr[num1].x === time) { student_chart.unshift(student_arr[num1]); num1++; } else { //为了防止数据库数据不全,数据库中没有的默认0 student_chart.unshift({ x: time, y: 0, s: 平均成绩, }); } }
两种方法各有优势,具体根据定时任务存储的时间而定.
语法方面也可进行优化,这里不做过多叙述.
如有更好的方法欢迎留言.
这里再分享几篇参考的文章以及感觉比较全面的MongoDB总结:
管道相关方法:
下一篇:
Redis 持久化(RDB 与AOF)