Sim. Você pode usar os Operadores de data com $substr e $concat para amarrar tudo junto.
db.test.aggregate([
{"$group": {
"_id" : { "$concat": [
{"$substr": [{"$year": "$date"}, 0, 4 ]},
"-",
{"$substr": [{"$month": "$date"}, 0, 2 ]},
"-",
{"$substr": [{"$dayOfMonth": "$date"}, 0, 2 ]},
]},
"count": {"$sum": 1 }
}},
{"$sort": { "_id": 1 }}
])
Você poderia usar apenas os operadores de data e fazer um documento como em:
"day": {
"year": {"$year": "$date" },
"month": {"$month": "$date"},
"day": {"$dayOfYear": "$date"}
}
Isso funciona tão bem. Mas isso lhe dá uma boa corda. Isso faz uso do fato de que
$substr
converterá de inteiro para string. Se isso for adicionado à documentação. Veja os Operadores de data documentação para uso nas outras divisões de tempo que podem ser usadas em datas.
Melhor ainda, use a matemática da data para retornar uma data BSON:
import datetime
db.test.aggregate([
{ "$group": {
"_id": {
"$add": [
{ "$subtract": [
{ "$subtract": [ "$date", datetime.datetime.utcfromtimestamp(0) ] },
{ "$mod": [
{ "$subtract": [ "$date", datetime.datetime.utcfromtimestamp(0) ] },
1000 * 60 * 60 * 24
]}
]},
datetime.datetime.utcfromtimestamp(0)
]
},
"count": { "$sum": 1 }
}},
{ "$sort": { "_id": 1 } }
])
Aqui
datetime.datetime.utcfromtimestamp(0)
será inserido no pipeline como uma data BSON representando "época". Quando você $subtract
uma Data BSON de outra é retornada a diferença em milissegundos. Isso permite "arredondar" a data para o dia atual subtraindo novamente o $mod
result para obter o restante da diferença de milissegundos de um dia. O mesmo vale para
$add
onde "adicionar" uma data BSON a um valor numérico resultará em uma data BSON.