4

我正在从 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"}

如果有人请求过去三十天的每日数字,那将意味着(在此示例中)“下载”公关的最大数量。天。这是当天的最后一条记录。

通过使用collection.find({"dt": {"$gt": datetime_obj_30_days_ago}}),我当然得到了所有的行,这不是很合适。因此,我正在寻找一种仅返回给定时间段内最后一天的方法。

有人告诉我这group()可能是要走的路,但我不太明白如何让它在这种情况下工作。

任何提示,指针将不胜感激!

4

1 回答 1

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) }'
)

请记住,它仍然对过去一个月进行线性扫描,只是在服务器上而不是客户端上。简单地单独选择每天的最大值可能会更快

于 2010-02-19T04:20:06.683 回答