小言_互联网的博客

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

336人阅读  评论(0)

说明:本文基于nest.js,typescript语法,mongoose,moment

目录

需要导的包:

第一种方法:正常循环 

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


前言:在网上找了很长时间,最终总结了如下两种方法,仅供参考  

需要导的包:

import * as moment from 'moment';

import { DateTime } from 'ts-luxon'; 

import { InjectModel } from '@nestjs/mongoose'; 

第一种方法:正常循环 


  
  1. //近七天趋势分析
  2. const water_rush_chart = [];
  3. for ( let i = 0; i < 7; i++) {
  4. const count = await this. WaterRushModel. aggregate([
  5. {
  6. $match: {
  7. create_time: {
  8. $gte: DateTime. local(). plus({ day: -i }). startOf( 'day'), //前i天的00:00
  9. $lte: DateTime. local(). plus({ day: -i }). endOf( 'day'), //前i天的59:59秒
  10. },
  11. },
  12. },
  13. //分组
  14. {
  15. $group: {
  16. _id: null, //根据什么分组
  17. value: { $sum: '$flow' }, //求需要的字段值之和,$sum为求和,$flow为字段
  18. dataDate: { $push: '$dataDate' },
  19. },
  20. },
  21. ]);
  22. water_rush_chart. unshift({
  23. x: DateTime. local()
  24. . plus({ day: -(i + 1) })
  25. . toFormat( 'LL-dd'), //转化为月-日
  26. y: count[ 0] ? count[ 0]. value. toFixed( 2) : 0,
  27. s: '数量',
  28. });
  29. }

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


  
  1. //近24小时趋势图
  2. const count1 = await this. studentModel. aggregate([
  3. {
  4. $match: {
  5. created_at: {
  6. $gte: DateTime. local(). plus({ hours: - 24 }). startOf( 'hour'),
  7. $lte: DateTime. local(). plus({ hours: - 1 }). endOf( 'hour'),
  8. },
  9. },
  10. },
  11. //分组
  12. {
  13. $group: {
  14. _id: {
  15. $subtract: [
  16. { $subtract: [ '$created_at', new Date( '1970-01-01')] },
  17. {
  18. $mod: [{ $subtract: [ '$created_at', new Date( '1970-01-01')] }, 1000 * 60 * 60 /*聚合时间段,24小时*/],
  19. },
  20. ],
  21. },
  22. name: { $push: '$pump_room_name' },
  23. score: { $avg: '$score' },
  24. time: { $push: '$created_at' },
  25. },
  26. },
  27. //排序
  28. {
  29. $sort: {
  30. time: 1,
  31. },
  32. },
  33. ]);
  34. //数据库查到的数据先存入数组
  35. const student_arr = [];
  36. count1. filter( (item) => {
  37. //添加平均成绩
  38. student_arr. unshift({
  39. x: moment(item. time[ 0]). format( 'HH:00'),
  40. y: item. score || 0,
  41. s: '平均成绩',
  42. });
  43. });
  44. //学生平均成绩趋势如(不包含当前小时)
  45. const studnet_chart = [];
  46. let num1 = 0;
  47. for ( let i = 0; i < 24; i++) {
  48. //获取当前时间
  49. const time = DateTime. local()
  50. . plus({ hour: -(i + 1) })
  51. . startOf( 'hour')
  52. . toFormat( 'HH:00');
  53. //判断所处时间是否有数据
  54. if (num1 < student_arr. length && student_arr[num1]. x === time) {
  55. student_chart. unshift(student_arr[num1]);
  56. num1++;
  57. } else {
  58. //为了防止数据库数据不全,数据库中没有的默认0
  59. student_chart. unshift({
  60. x: time,
  61. y: 0,
  62. s: '平均成绩',
  63. });
  64. }
  65. }

两种方法各有优势,具体根据定时任务存储的时间而定.

语法方面也可进行优化,这里不做过多叙述.

如有更好的方法欢迎留言.

这里再分享几篇参考的文章以及感觉比较全面的MongoDB总结:

http://t.csdn.cn/ERi3A

http://t.csdn.cn/ZYBDR

 http://t.csdn.cn/K0MGK

管道相关方法:

http://t.csdn.cn/jekcX


转载:https://blog.csdn.net/m0_46420244/article/details/128496643
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场