我有一个查询(对于一个MongoDB数据库),它返回已经mapreduced的对象,每15分钟报告一次对象,但问题是如果说我们在其中一个服务器中有一个严重错误,那段时间将是下落不明。
以此数组为例:
[
{:timestamp=>2011-09-26 19:00:00 UTC, :count=>318},
{:timestamp=>2011-09-26 19:15:00 UTC, :count=>308},
{:timestamp=>2011-09-26 19:30:00 UTC, :count=>222},
{:timestamp=>2011-09-26 19:45:00 UTC, :count=>215},
{:timestamp=>2011-09-26 20:00:00 UTC, :count=>166},
{:timestamp=>2011-09-26 21:15:00 UTC, :count=>149},
{:timestamp=>2011-09-26 21:30:00 UTC, :count=>145},
{:timestamp=>2011-09-26 21:45:00 UTC, :count=>107},
{:timestamp=>2011-09-26 22:00:00 UTC, :count=>137},
{:timestamp=>2011-09-26 22:15:00 UTC, :count=>135},
{:timestamp=>2011-09-26 22:30:00 UTC, :count=>191},
{:timestamp=>2011-09-26 22:45:00 UTC, :count=>235}
]
您会注意到时间范围内缺少时间:
{:timestamp=>2011-09-26 20:15:00 UTC},
{:timestamp=>2011-09-26 20:30:00 UTC},
{:timestamp=>2011-09-26 20:45:00 UTC},
{:timestamp=>2011-09-26 21:00:00 UTC}
如何将顶部作为输入并推断出那些将是缺失的行?时间增量总是15分钟,它实际上是一个真实的日期对象,而不是像这样的字符串。
我无法想象如何迭代这个。
非常感谢任何帮助。
答案 0 :(得分:3)
我能想到的最简单的方法是按时间戳排序数组,然后执行以下操作:
missing_times = []
reports.each_with_index do |report, index|
if reports[index + 1]
if report.timestamp.advance(minutes: 15) < report[index + 1].timestamp
i = 0
while(report.timestamp.advance(minutes: 15*i) < report[index+1].timestamp)
missing_times << report.timestamp.advance(minutes: 15*i)
end
end
end
end
我之前写过类似的代码,可以在一系列约会中找到半小时的差距
虽然看起来我的解决方案会在reports.first和reports.last之间以15分钟为增量循环多次,但它实际上只会在reports.first和reports.last
之间的所有可用增量上循环一次。答案 1 :(得分:1)
如果您以15分钟为增量创建总时间跨度的数组,并且只是与报告集进行比较并删除任何匹配项,而不是在循环内执行多个循环,对于大型数据集会更有效。
start_time = report.first
span = ((report.last - start_time)/60/15).to_i # this gives the number of 15min blocks
test_array = []
span.times do |i|
test_array << start_time + i*15.minutes
end
report.each do |r|
test_array.delete(r) # or in your case, r.timestamp
end
我认为它有效,但想不出一个制作时间戳参考表的好方法,所以我在那里破解了。
答案 2 :(得分:0)
只需从第一个时间戳开始,然后递增15分钟,验证该条目是否存在,并继续前进,直至到达上一个时间戳。