我有很多文件,其中包含选择日期和地点ID。我正在尝试构建一个管道,该管道将匹配文档,其选择时间在最后一小时内,然后对这些管道进行计数。我的日期是mm-dd-yyyy hh:mm:ss格式,但似乎在MongoDB中表示为字符串
这是我到目前为止所拥有的
last_hour = datetime.datetime.now() - datetime.timedelta(minutes=60)
now = dateime.datetime.now()
pipeline = [
{"$match":{"select_time":{"$gt":last_hour,"$lte":now}}},
{"$unwind":"$loc_id"},
{"$group": {"_id":"$loc_id"}},
{"$sort": SON([("_id", -1), ("count", -1)])}
]
for i in list(db.loc_counter.aggregate(pipeline)):
print i
除了匹配件之外的所有东西都在工作。我不确定这是一个日期格式问题还是什么。
答案 0 :(得分:2)
将当前时间格式转换为ISODate格式。
您可能需要编写迁移以将当前select_time
转换为ISODate格式(See supported formats。)
当集合中的文档数量巨大时,管道的投影阶段可能变得低效。
另外,修复以错误日期格式插入文档的脚本,以ISODate格式插入带有select_time
字段的文档。
lasthour = datetime.now() - timedelta(hours=1)
pipeline = [
{
'$project': {
'select_time_ISODate': {
'$dateFromString': {
'dateString': {
'$concat': [
{'$substr': ['$select_time', 6, 4]},
'-', {'$substr': ['$select_time', 0, 2]},
'-', {'$substr': ['$select_time', 3, 2]},
'T', {'$substr': ['$select_time', 11, 8]}
]
}
}
},
'loc_id': 1
}
},
{'$match': {'select_time_ISODate': {'$gte': lasthour}}},
{'$count': 'num_logs_since_past_hour'}
]
cursor = db.loc_counter.aggregate(pipeline)
print(tuple(cursor))
假设select_time
采用正确的日期格式,您只需要当前管道的匹配和计数阶段。
答案 1 :(得分:0)
$ dateFromString 工作正常,但我的建议是将select_time存储为仅 ISO日期。存储为字符串的日期时间格式无用,您不能将它们用于排序或日期比较条件。每次将select_time投影为ISO日期时都将是一个不必要的管道。