我正在从Web服务收集一些统计信息,并将其存储在集合中。数据与此类似(但有更多字段):
{"downloads": 30, "dt": "2010-02-17T16:56:34.163000"}
{"downloads": 30, "dt": "2010-02-17T17:56:34.163000"}
{"downloads": 30, "dt": "2010-02-17T18:56:34.163000"}
{"downloads": 30, "dt": "2010-02-17T19:56:34.163000"}
{"downloads": 30, "dt": "2010-02-17T20:56:34.163000"}
{…}
{"downloads": 30, "dt": "2010-02-18T17:56:34.163000"}
{"downloads": 30, "dt": "2010-02-18T18:56:34.163000"}
{"downloads": 30, "dt": "2010-02-18T19:56:34.163000"}
{"downloads": 30, "dt": "2010-02-18T20:56:34.163000"}
如果有人要求过去30天的每日数字,那就意味着(在此示例中)'下载'pr的最大数量。天。这是当天的最后一条记录。
通过使用collection.find({"dt": {"$gt": datetime_obj_30_days_ago}})
,我当然得到了所有的行,这不是很合适。所以我正在寻找一种方法,只返回给定时期内的最后一天。
我被告知group()
可能是要走的路,但我不太明白如何让它在这种情况下运作。
任何提示,指示都会非常感激!
答案 0 :(得分:1)
您可以使用group执行此操作。在您的示例中,您需要提供一个javascript函数来计算密钥(以及reduce函数),因为您只需要datetime字段的日期组件。这应该有效:
db.coll.group(
key='function(doc) { return {"dt": doc.dt.toDateString()} }',
condition={'dt': {'$gt': datetime_obj_30_days_ago}},
initial={'downloads': 0},
reduce='function(curr, prev) { prev.downloads = Math.max(curr.downloads, prev.downloads) }'
)
请记住,仍然会对服务器而不是客户端进行过去一个月的线性扫描。 可能只需单独选择每天的最大值就可以了。