2012-01-30 46 views
1

背景找到最接近给定的时间记录在Ruby on Rails的

我有一个RoR应用程序被连续记录并显示在网站上实时传感器数据。然后我有一个名为传感器的表,它具有所有传感器的唯一列表并存储最新值。

我还有另一个表历史其中转储所有传感器值收到每个传感器。

所以关系“检测器有许多历史”,则TIME-STAMP山坳记录的创建时间戳记。

并非所有传感器都以相同的间隔或频率更新。

问题

现在我想从繁重的用户,在过去的日期和时间的输入时间戳记,并显示哪些传感器被一同显示。例如,假设我想在昨天下午2点看到所有传感器看起来像什么,一旦我从用户那里得到这个时间戳,我如何从历史记录表中找到最接近输入时间戳的一个传感器值。

我期待在传感器模型中添加一个方法,该方法将time_stamp作为参数,并从历史记录表中检索最接近输入time_stamp的值。

他们写这个Active记录查询的最简单方法是什么?

感谢 Shaunak

回答

8

只是根据通过时间戳和历史时间戳(绝对值,因此它可以在任何一个方向走),并返回顶端的结果(这是一个与之间的差异的历史排序最小差异)。

sensor.histories.order("ABS(time_stamp - #{params[:time_stamp].to_i})").first 

请注意,此查询我假设你正在使用MySQL(因为我使用的是MySQL法ABS),我也假设time_stamp场被存储为Unix时间戳和用户输入同样。如果数据库存储或输入格式不同,则必须使用不同的日期算术函数。详情请参阅http://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html。或者,如果您不使用MySQL,请参阅您正在使用的数据库的文档。

另请注意,我正在使用.to_i来清理查询中的数据。如果您的数据格式不同,则可能需要以不同的方式对其进行消毒。

为了使效率更高,请在最大可能范围内将其限制为time_spans。如果传感器每10分钟或更频繁地采集数据(读数之间间隔不少于10分钟),则每侧超过10分钟的范围将会执行。像下面的东西。在这里,600 = 10(分钟)* 60(秒):

sensor.histories.where("time_stamp >= ? AND time_stamp <= ?", params[:time_stamp].to_i - 600, params[:time_stamp].to_i + 600).order("ABS(time_stamp - #{params[:time_stamp].to_i})").first 

这是简单的将其转换为一个模型方法:

class Sensor < ActiveRecord::Base 
    def history_at(time_stamp) 
     self.histories.where("time_stamp >= ? AND time_stamp <= ?", time_stamp.to_i - 600, time_stamp.to_i + 600).order("ABS(time_stamp - #{time_stamp.to_i})").first 
    end 
end 
+0

感谢一个快速的答案!在关闭之前还有一件事,每个传感器每10分钟更新一次,并且我有大约一年的数据!所以每次我想要读取一个传感器的值时,不要整理整个事物需要很多时间?是否有某种方法可以根据输入时间戳对一些跨度进行优化,从而优化查询?我正在使用MS SQL Server 2008.再次感谢! – Shaunak 2012-01-31 01:09:35

+0

是的,您可以将其限制为仅考虑合理的时间戳。我用一些细节更新了我的答案。 – 2012-01-31 01:17:01

+0

太棒了!会尝试一下,让你知道!谢谢! – Shaunak 2012-01-31 01:21:04