问题
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