group by day/month and take average of rating on that day/month in mongo

别说谁变了你拦得住时间么 提交于 2019-12-22 05:21:59

问题


I have this data in 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")
  }
]

I need to take the average of rating for that particular day/month depending upon the filter criteria. if the filter range for date is less than a month then it will be grouped basis on day. if filter range for date is more than a month, then it will be grouped basis on month.

This is what I am kind of expecting

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

How can I do it in mongodb?


回答1:


To group documents by day/month and return the month key in your output, you need to first $project the key fields to appropriate formats using the Date operators, in particular the $dateToString and $month operators.

This can be done in a $project stage prior to the $group step but not necessary since the $group pipeline accommodates mostly the accumulator operators.

In the preceding $group pipeline, you can the group the documents by the formatted date key, aggregate using the $avg operator and return the month as an integer from the previous pipeline using $first accumulator operator.

Running the following aggregation pipeline should give you the desired result:

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



回答2:


For the collection, use an aggregate() to $group, with the grouping _id of the $month from the ceatedAt (sic) field of your documents, and make the month field in the outputted document equal that value.

Then, create a field named ceatedAt that uses $dateToString to format the $date field of the inputted document as "%Y-%m-%d".

Finally, create a field named average, that is the $avg of the $rating field of the inputted document, in your grouped documents.

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"
    }
  }
])


来源:https://stackoverflow.com/questions/38897478/group-by-day-month-and-take-average-of-rating-on-that-day-month-in-mongo

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!