Influxdb: вычисление продолжительности логических событий?

У меня есть данные в базе InfxDB от датчика двери. Это логический датчик (либо дверь открыта (значение false), либо закрыта (значение true)), а таблица выглядит так:

name: door
--------------
time            value
1506026143659488953 true
1506026183699139512 false
1506026751433484237 true
1506026761473122666 false
1506043848850764808 true
1506043887602743375 false

Я хотел бы подсчитать, как долго дверь была открыта в данный период времени. Функция ELAPSED приближает меня, но я не уверен, как либо (а) ограничить его только теми интервалами, для которых начальное значение равно false, либо (б) идентифицировать «открытые» интервалы из вывода чего-то вроде select elapsed(value, 1s) from door.

Я надеялся, что смогу сделать что-то вроде:

select elapsed(value, 1s), first(value) from door

Но это не дает мне ничего полезного:

name: door
--------------
time            elapsed first
0               true
1506026183699139512 40  
1506026751433484237 567 
1506026761473122666 10  
1506043848850764808 17087   
1506043887602743375 38  

Я надеялся на нечто большее, например:

name: door
--------------
time            elapsed first
1506026183699139512 40  true
1506026751433484237 567 false
1506026761473122666 10  true
1506043848850764808 17087   false
1506043887602743375 38  true

Если не считать самого извлечения данных и их обработки, например, python, есть ли способ сделать это с помощью запроса infxdb?


person larsks    schedule 22.09.2017    source источник
comment
не похоже, что он поддерживается сегодня - stackoverflow.com/questions/27959196/. Отсутствие встроенной поддержки запросов также означает, что эту информацию невозможно отобразить в таких инструментах визуализации, как Grafana. У меня есть это только для работы с обработкой на стороне клиента и добавления дополнительной информации в измерение, которое можно использовать для рендеринга в Grafana.   -  person Vinod    schedule 25.09.2017


Ответы (3)


Я тоже столкнулся с этой проблемой, я хотел просуммировать продолжительность времени, в течение которого установлен флаг, что довольно часто встречается при обработке сигналов в библиотеках временных рядов, но Influxdb, похоже, не очень хорошо поддерживает это. Я попробовал INTEGRATE с флагом значения 1, но мне показалось, что он не дает мне правильных значений. В конце концов, я просто рассчитал интервалы в моем источнике данных, опубликовал их как отдельное поле в infxdb и суммировал их. Так это работает намного лучше.

person Luc    schedule 11.10.2018

Это самое близкое, что я нашел до сих пор:

https://community.influxdata.com/t/storing-duration-in-influxdb/4669

Идея состоит в том, чтобы сохранить логическое событие как 0 или 1 и сохранять каждое изменение состояния с двумя записями с одной единицей разницы во времени. Это выглядело бы примерно так:

name: door
--------------
time            value
1506026143659488953 1
1506026183699139511 1
1506026183699139512 0
1506026751433484236 0
1506026751433484237 1
1506026761473122665 1
1506026761473122666 0
1506043848850764807 0
1506043848850764808 1
1506043887602743374 1
1506043887602743375 0

Тогда можно будет использовать такой запрос:

SELECT integral(value) FROM "door" WHERE time > x and time < y

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

person MrBerta    schedule 21.02.2020

У меня была такая же проблема. После того, как я наткнулся на эту стену с InfluxDB и не нашел никаких чистых решений здесь или где-либо еще, я в конечном итоге переключился на TimescaleDB (на основе PostgreSQL) и решил его с помощью SQL оконная функция, использующая lag() для вычисления дельты предыдущего значения времени.

Для набора данных OP возможное решение выглядит следующим образом:

SELECT
  "time",
  ("time" - lag("time") OVER (ORDER BY "time"))/1000000000 AS elapsed,
  value AS first
FROM door
ORDER BY 1
OFFSET 1;  -- omit the initial zero value

Вход:

CREATE TEMPORARY TABLE "door" (time bigint, value boolean);
INSERT INTO "door" VALUES
  (1506026143659488953, true),
  (1506026183699139512, false),
  (1506026751433484237, true),
  (1506026761473122666, false),
  (1506043848850764808, true),
  (1506043887602743375, false);

Вывод:

        time         | elapsed | first 
---------------------+---------+-------
 1506026183699139512 |      40 | f
 1506026751433484237 |     567 | t
 1506026761473122666 |      10 | f
 1506043848850764808 |   17087 | t
 1506043887602743375 |      38 | f
(5 rows)
person jrc    schedule 09.10.2020
comment
Очень хорошо! Раньше я немного работал с timescaledb, но тогда меня разочаровало отсутствие политик хранения данных. Похоже, с тех пор, как я последний раз смотрел, все могло измениться. - person larsks; 09.10.2020
comment
Похоже, у InfluxDB 2 есть собственное решение: docs. Influxdata.com/influxdb/v2.0/query-data/flux/ - person jrc; 26.05.2021