You basically already are by using the date aggregation operators to split up the components into your compound _id
key, and this is probably the best way to handle it. You can actually alter this though with the $substr
operator and use of $concat
:
db.event.aggregate([
{ "$project": {
"created": {$add: ["$created", 60*60*1000*8]},
}},
{ "$group": {
"_id": {
"year": {"$year": "$created"},
"month": {"$month": "$created"},
"day": {"$dayOfMonth": "$created"}
},
"count": { "$sum": 1 }
}},
{ "$project": {
"_id": { "$concat": [
{ "$substr": [ "$_id.year", 0, 4 ] },
"-",
{ "$cond": [
{ "$lte": [ "$_id.month", 9 ] },
{ "$concat": [
"0",
{ "$substr": [ "$_id.month", 0, 2 ] }
]},
{ "$substr": [ "$_id.month", 0, 2 ] }
]},
"-",
{ "$cond": [
{ "$lte": [ "$_id.day", 9 ] },
{ "$concat": [
"0",
{ "$substr": [ "$_id.day", 0, 2 ] }
]},
{ "$substr": [ "$_id.day", 0, 2 ] }
]}
]},
"count": 1
}}
])
So there is a bit of coercion of the values from the date parts to strings there as well as padding out any values under two didgits with a leading 0 just like in a "YYYY-MM-DD" format.
Noting that it can be done, and has been able to be done for some time, but it is notably missing from the manual page description of the $substr
operator.
Not to sure about your "date math" at the start there. I would say you would be better off using the aggregation operators and then working on the values that you wanted to adjust by, or if indeed it was something like a "timezone" correction, then again you would probably be better off processing that client side.