关于MongoDB处理统计图数据(按天,小时)

时间:2025-02-16 14:42:00

说明:本文基于,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 ([
          {
            $match: {
              create_time: {
                $gte: ().plus({ day: -i }).startOf('day'),//前i天的00:00
                $lte: ().plus({ day: -i }).endOf('day'),//前i天的59:59秒
              },
            },
          },
            //分组
          {
            $group: {
              _id: null,    //根据什么分组
              value: { $sum: '$flow' },    //求需要的字段值之和,$sum为求和,$flow为字段
              dataDate: { $push: '$dataDate' },
            },
          },
        ]);

        water_rush_chart.unshift({
          x: ()
            .plus({ day: -(i + 1) })
            .toFormat('LL-dd'),    //转化为月-日
          y: count[0] ? count[0].(2) : 0,
          s: '数量',
        });
      }

第二种方法:通过分组将数据按照所需时间分组 

//近24小时趋势图
      const count1 = await ([
        {
          $match: {
            created_at: {
              $gte: ().plus({ hours: -24 }).startOf('hour'),
              $lte: ().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 = [];
      ((item) => {
        //添加平均成绩
        student_arr.unshift({
          x: moment([0]).format('HH:00'),
          y:  || 0,
          s: '平均成绩',
        });
      });

      //学生平均成绩趋势如(不包含当前小时)
      const studnet_chart = [];
      let num1 = 0;
      for (let i = 0; i < 24; i++) {
        //获取当前时间
        const time = ()
          .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总结:

/ERi3A

/ZYBDR

 /K0MGK

管道相关方法:

/jekcX