найти запись, ближайшую к заданному времени в ruby ​​на рельсах - PullRequest
1 голос
/ 31 января 2012

Фон

У меня есть приложение ror, которое постоянно записывает и отображает на веб-сайте данные датчика в реальном времени.Затем у меня есть таблица под названием Датчики , в которой содержится уникальный список всех датчиков и хранятся последние значения.

У меня также есть другая таблица историй , в которой выводятся все значения датчиков, когда-либо полученные для каждого датчика.

Таким образом, отношение "у датчика многоhistory ", столбец time_stamp записывает метку времени создания.

Не все датчики обновляются с одинаковым интервалом или частотой.

Проблема

Теперь я хочу получить отметку времени ввода от пользователя, дату ивремя в прошлом, и показать, что датчики показывали в то время.Например, я хочу посмотреть, как вчера выглядели все датчики в 2 часа дня, как только у меня есть эта отметка времени от пользователя, как мне извлечь значение одного датчика, ближайшее к отметке времени ввода из таблицы истории.

Я хочу добавить метод в модель датчика, который будет принимать time_stamp в качестве аргумента и извлекать значение, наиболее близкое к входному time_stamp из таблицы истории.

Какой самый простой способ написать этоАктивная запись запроса?

Спасибо, Шаунак

1 Ответ

8 голосов
/ 31 января 2012

Просто отсортируйте истории в соответствии с разницей между переданной отметкой времени и отметкой времени истории (абсолютное значение, чтобы она могла двигаться в любом направлении), и верните максимальный результат (это результат с наименьшей разницей).

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
...