我无法在字段上按月分组,值为时间戳。
Collection(Dummy):
{
"created_at": 1232341243
}, {...}, ...
现在,如果我想使用$month按月聚合这个集合的文档,它会抛出以下错误:
db.getCollection('dummy').aggregate([{"$group": {"_id": {"$month": "$created_at"}}}])
Error message
"errmsg" : "can't convert from BSON type int to Date",
MongoDB版本:3.6.3
让我们从$month支持哪些类型的输入开始:
日期、时间戳或ObjectID。
所以对于Mongo 4.0+版本,你可以使用$toDate将一个有效的(数字)ts或有效的日期字符串转换为Date
对象,如下所示:
{"$group": {"_id": {"$month": {"$toDate":"$created_at"}}}}
如果您使用的是较早的Mongo版本,并且无法访问此函数,您可以使用"hacky"使用$add进行聚合,当它获得一个数字和一个日期类型时,它将返回一个日期类型。
唯一需要注意的是,您需要将时间戳(用从epoch 0开始的秒表示)转换为毫秒。即乘以1000,如下所示:
from datetime import datetime
...
{
"$group": {
"_id": {
"$month": {
'$add': [
datetime(1970, 1, 1),
{'$multiply': ["$created_at", 1000]}
]
}
}
}
}
您可以先转换"created_at"使用"addFields"阶段,
{
$addFields: {
convertedDate: {"$toDate":"$created_at"}
}
}
在之后,您可以执行进一步的操作。最后你对聚合的查询会是这样的,对于版本3.6
[
{
'$project': {
"convertedDate": { "$add": [ new Date(0), "$created_at" ] }
}
},
{
'$project': {
'month': {
'$month': '$convertedDate'
},
'year': {
'$year': '$convertedDate'
}
}
}, {
'$group': {
'_id': {
'month': '$month',
'year': '$year'
},
'total': {
'$sum': 1
},
'month': {
'$first': '$month'
},
'year': {
'$first': '$year'
}
}
}
]
版本4+
[
{
'$addFields': {
'convertedDate': {"$toDate":"$created_at"}
}
},
{
'$project': {
'month': {
'$month': '$convertedDate'
},
'year': {
'$year': '$convertedDate'
}
}
}, {
'$group': {
'_id': {
'month': '$month',
'year': '$year'
},
'total': {
'$sum': 1
},
'month': {
'$first': '$month'
},
'year': {
'$first': '$year'
}
}
}
]