按日/月分组,并在mongo中取得该日/月的评级平均值

时间:2016-08-11 13:15:41

标签: mongodb date group-by

我在mongodb中有这些数据:

[
  {
    "rating": 4,
    "ceatedAt": ISODate("2016-08-08T15:32:41.262+0000")
  },
  {
    "rating": 3,
    "createdAt": ISODate("2016-08-08T15:32:41.262+0000")
  },
  {
    "rating": 3,
    "ceatedAt": ISODate("2016-07-01T15:32:41.262+0000")
  },
  {
    "rating": 5,
    "createdAt": ISODate("2016-07-01T15:32:41.262+0000")
  }
]

我需要根据过滤条件获取该特定日/月的评级平均值。 如果日期的过滤范围小于一个月,那么它将按天分组。如果日期的过滤范围超过一个月,那么它将按月分组。

这就是我所期待的

[
  {
    "average": 3.5,
    "ceatedAt": "2016-08-08",
    "month": "August"
  },
  {
    "average": 4,
    "ceatedAt": 2016-07-01,
    "month": "July"
  }
]

我怎么能在mongodb中做到这一点?

2 个答案:

答案 0 :(得分:3)

要按天/月分组文档并在输出中返回月份密钥,您需要先使用$project运算符 Date 关键字段以获取相应的格式,特别是 $dateToString $month 运营商。

这可以在 $project 步骤之前的 $group 阶段完成,但不是必需的,因为 {{3} 管道主要适用于$group运营商。

在前面的 accumulator 管道中,您可以按格式化的日期键对文档进行分组,使用 $group 运算符进行汇总并返回使用 $avg 累加器运算符将月份作为上一个管道中的整数。

运行以下聚合管道应该可以获得所需的结果:

db.collection.aggregate([
  { "$group": {
    "_id": { 
        "$dateToString": { "format": "%Y-%m-%d", "date": "$ceatedAt" } 
    },
    "average": { "$avg": "$rating" },
    "month": { "$first": { "$month": "$ceatedAt" } },
  } }
]) 

答案 1 :(得分:1)

对于集合,请使用aggregate()$group,并使用文档_id(原文如此)字段中$month的分组ceatedAt ,并使输出文档中的month字段等于该值。

然后,创建一个名为ceatedAt的字段,该字段使用$dateToStringformat输入文档的$date字段"%Y-%m-%d"

最后,在您的分组文档中创建一个名为average的字段,即输入文档的$avg字段的$rating

db.collection.aggregate([
  {
    $group: {
      _id: { month: { $month: "$ceatedAt" } },
      date: { first: "$ceatedAt" },
      average: { $avg: "$rating" }
    }
  },
  {
    $project: {
      month: "$month",
      ceatedAt: { $dateToString: { format: "%Y-%m-%d", date: "$date" } },
      average: "$average"
    }
  }
])