2012-01-30 55 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