首页 > 解决方案 > Mongo每天汇总$group?

问题描述

我有一个历史集合,并希望基于该集合创建导出数据库

[{
_id: "...",
value: 10,
at: ISODate("2021-24-06T00:01:02.023")
}, {
_id: ...,
value: 13,
at: ISODate("2021-24-06T00:04:11.211")
}, {
_id: ...,
value: 12,
at: ISODate("2021-24-06T09:11:31.182")
}, {
_id: ...,
value: 40,
at: ISODate("2021-24-07T01:33:31.723")
}, {
_id: ...,
value: 40,
at: ISODate("2021-24-15T09:32:44.983")
}, {
_id: ...,
value: 40,
at: ISODate("2021-24-16T10:43:22.083")
}, {
_id: ...,
value: 40,
at: ISODate("2021-24-16T14:43:22.083")
}, {
_id: ...,
value: 40,
at: ISODate("2021-24-17T04:25:12.021")
}, {
_id: ...,
value: 40,
at: ISODate("2021-24-18T20:13:22.083")
}, {
_id: ...,
value: 40,
at: ISODate("2021-24-19T18:41:22.083")
}]

我必须按以下方式公开 3 个选项组:小时、天、周

我正在尝试使用 $group 来计算一天中的混合/最大值或平均值,但不知道如何将它们分组到每小时/每天/每周的数据中

我可以按 $cond 分组吗?因为它对所有情况都非常灵活。

示例:按小时分组,第一时刻 = 2021-24-06T00:00:00.000 预期:

[{
  at: ISODate("2021-24-06T00:00:00.000"),
  max: 13,
  min: 10,
  avg: 21.5
}, {
  at: ISODate("2021-24-06T01:00:00.000"),
}, ..., {
  at: ISODate("2021-24-06T09:00:00.000"),
  max: 12,
  min: 12,
  avg: 12
}]

分组依据 = 天

预计:

[{
  at: ISODate("2021-24-06T00:00:00.000"),
  max: 13,
  min: 10,
  avg: 11.7
}, {
  at: ISODate("2021-24-07T00:00:00.000"),
  max: 40,
  min 40,
  avg: 40,
}]

这是我的想法。创建每个组的第一个时刻,at与组的第一个时刻和最后一个时刻进行比较。

例如:按天分组,第一组的第一时刻在:ISODate("2021-24-06T00:00:00.000")->最后时刻= ISODate("2021-24-06T23:59:59.999")->分组所有记录属于该组

第二组:ISODate("2021-24-06T00:00:00.000")+ 1day = ISODate("2021-24-07T00:00:00.000")-> last moment = ISODate("2021-24-07T23:59:59.999")-> Group 所有记录属于该组

但是如何实现

标签: node.jsmongodbgroup-byaggregation

解决方案


您可以$dateToString在 Group By$group子句中使用基于Day&对数据进行分组Hour。您可以$week在 Group By$group子句中使用基于Week.

请看下面的代码:

样本数据 样本数据

按周分组

db.collData.aggregate([
  {
    $group : {
       _id : { $week: '$at' },
       averageValue: { $avg: "$value" },
       count: { $sum: 1 }
    }
  },
  {
    $sort : { averageValue: -1 }
  }
])

按周分组

按天分组

db.collData.aggregate([
  {
    $group : {
       _id : { $dateToString: { format: "%Y-%m-%d", date: "$at" } },
       averageValue: { $avg: "$value" },
       count: { $sum: 1 }
    }
  },
  {
    $sort : { averageValue: -1 }
  }
])

按天分组

按小时分组

db.collData.aggregate([
  {
    $group : {
       _id : { $dateToString: { format: "%Y-%m-%dT%H", date: "$at" } },
       averageValue: { $avg: "$value" },
       count: { $sum: 1 }
    }
  },
  {
    $sort : { averageValue: -1 }
  }
])

按小时分组

查看更多详情$group

查看更多详情$dateToString

查看更多详情$week

在查询中使用 TimeZone 更新

您可以timezone$dateToString表达式中使用。请检查以下示例:

组中添加的时区由

db.collData.aggregate([
  {
    $group : {
       _id : { $dateToString: { format: "%Y-%m-%d", date: "$at", timezone: "-05:00" } },
       averageValue: { $avg: "$value" },
       count: { $sum: 1 }
    }
  },
  {
    $sort : { averageValue: -1 }
  }
])

db.collData.aggregate([
  {
    $group : {
       _id : { $dateToString: { format: "%Y-%m-%d", date: "$at", timezone: "+07:00" } },
       averageValue: { $avg: "$value" },
       count: { $sum: 1 }
    }
  },
  {
    $sort : { averageValue: -1 }
  }
])

您将在下面的链接中找到有关表达式的更多信息,包括timezone.

MongoDB $dateToString

timezone在小时示例中添加:

db.collData.aggregate([
  {
    $group : {
       _id : { $dateToString: { format: "%Y-%m-%dT%H", date: "$at", timezone: "+00:30" } },
       averageValue: { $avg: "$value" },
       count: { $sum: 1 }
    }
  },
  {
    $sort : { averageValue: -1 }
  }
])

timezone在周示例中添加:

db.collData.aggregate([
  {
    $group : {
       _id : { $week: { date: '$at', timezone: "-05:00" } },
       averageValue: { $avg: "$value" },
       count: { $sum: 1 }
    }
  },
  {
    $sort : { averageValue: -1 }
  }
])

推荐阅读