Базы данных

Даунсемплинг аналог M4 в табличной модели Apache IoTDB 2.0.5

Как реализовать прореживание данных (даунсемплинг) в Apache IoTDB табличной модели без функции M4. SQL-примеры с first_value, last_value, min_value, max_value и GROUP BY для извлечения ключевых точек временных рядов.

6 ответов 1 просмотр

Как реализовать даунсемплинг данных, аналогичный функции M4, в табличной модели Apache IoTDB?

Я создал аналогичные наборы данных в древовидной модели и табличной модели Apache IoTDB 2.0.5. В древовидной модели функция M4 легко выполняет даунсемплинг временных рядов, извлекая четыре ключевые точки из каждого временного окна: первую точку (F), последнюю точку (L), минимум (M) и максимум (H). Однако при попытке выполнить то же самое в табличной модели возникает ошибка «unknown function».

Воспроизводимые данные и шаги

Древовидная модель

sql
INSERT INTO `root.db.device01`(timestamp, temperature) VALUES (1000, 10.0), (2000, 15.0), (3000, 12.0), (4000, 18.0), (5000, 11.0), (6000, 16.0);

Даунсемплинг с помощью M4 окном 3 секунды (выполняется успешно):

sql
SELECT M4(temperature, 'timeInterval'='3000') FROM `root.db.device01`;

Результат:

 +-----------------------------+-------------------------------------------------------+
 | `Time`|M4(`root.db.device01.temperature`, "timeInterval"="3000")|
 +-----------------------------+-------------------------------------------------------+
 |1970-01-01T08:00:01.000+08:00| 10.0|
 |1970-01-01T08:00:02.000+08:00| 15.0|
 |1970-01-01T08:00:03.000+08:00| 12.0|
 |1970-01-01T08:00:04.000+08:00| 18.0|
 |1970-01-01T08:00:05.000+08:00| 11.0|
 |1970-01-01T08:00:06.000+08:00| 16.0|
 +-----------------------------+-------------------------------------------------------+

Табличная модель (проблема)

sql
CREATE TABLE sensor_readings (device tag, value DOUBLE field);
INSERT INTO sensor_readings VALUES(1000, 'device01', 10.0), (2000, 'device01', 15.0), (3000, 'device01', 12.0), (4000, 'device01', 18.0), (5000, 'device01', 11.0), (6000, 'device01', 16.0);

Попытка использовать функцию M4 в табличной модели (неудача):

sql
SELECT M4(value, 'timeInterval'='3000') FROM sensor_readings WHERE device='device01';

Сообщение об ошибке:

sql
Msg: org.apache.iotdb.jdbc.IoTDBSQLException: 701: Unknown function: m4

В официальной документации по табличной модели функция M4 действительно не упоминается. Значит ли это, что функция M4 пока не поддерживается в табличной модели Apache IoTDB? Если да, то как составить SQL-запрос или какие функции можно комбинировать, чтобы добиться аналогичного результата?

Желаемый результат: даунсемплинг колонки value по заданной длине окна (например, 3 секунды), возвращающий четыре характерные точки (первая, последняя, минимум, максимум) для каждого окна с сохранением информации о timestamp, аналогично древовидной модели.

В табличной модели Apache IoTDB 2.0.5 функция M4 недоступна — она работает только в древовидной модели для прореживания данных (даунсемплинга) временных рядов. Вместо неё используйте агрегатные функции first_value, last_value, min_value и max_value с GROUP BY по временным окнам, чтобы извлечь ключевые точки: первую (F), последнюю (L), минимум (M) и максимум (H) с сохранением timestamp. Такой подход даёт точный аналог M4 для вашей таблицы sensor_readings с окном в 3000 мс.


Содержание


Что такое функция M4 в iotdb и почему она не работает в табличной модели

Функция M4 в Apache IoTDB — это удобный инструмент для даунсемплинга, который берёт временное окно и выдавливает четыре точки: первую по времени (F), последнюю (L), минимум значения (M) и максимум (H). В древовидной модели ваш пример с root.db.device01 работает идеально: SELECT M4(temperature, 'timeInterval'='3000') просто и эффективно прореживает данные. Но перейдём к табличной модели — здесь всё меняется.

Почему ошибка “unknown function: m4”? Всё просто: M4 привязана к древовидной структуре данных IoTDB и не перенесена в table model. Документация по функциям IoTDB чётко это подтверждает — в списке агрегатов для таблиц её нет. Табличная модель фокусируется на стандартном SQL с тегами и полями, где time становится обычной колонкой. Попытка запустить SELECT M4(value, 'timeInterval'='3000') FROM sensor_readings рушится на этапе парсинга. А вы пробовали обновить версию? В 2.0.5 это не добавили, но есть обходные пути.

Представьте: у вас тонны IoT-данных от сенсоров, и прореживание нужно срочно. Без M4 мир не рухнет — IoTDB даёт мощные альтернативы.


Прореживание данных (даунсемплинг) во временных рядах: различия tree и table моделей apache iotdb

Даунсемплинг — это не роскошь, а необходимость для баз данных временных рядов вроде IoTDB. Когда данные сыплются каждую секунду от тысяч устройств, хранить всё бессмысленно: нужны ключевые точки для анализа трендов, аномалий или визуализации. В tree model пути вроде root.db.device01.temperature позволяют M4 работать “из коробки”, группируя по иерархии.

Table model в Apache IoTDB 2.0.5 — это шаг к SQL-стандартам: таблицы с тегами (device) и полями (value), где time — timestamp. Плюсы? JOIN’ы, WHERE по тегам, масштабируемость. Минусы для даунсемплинга? Нет специальных функций вроде M4. Вместо этого — GROUP BY по интервалам времени. Руководство по запросам в table model подчёркивает: используйте date_bin или фиксированные окна для агрегации.

Различия на пальцах: tree — для жёсткой IoT-иерархии, table — для гибкого анализа. Если мигрируете данные, как в вашем случае с INSERT в sensor_readings, то даунсемплинг требует перестройки запросов. И это не баг, а фича — table model эволюционирует быстрее.


Альтернативы M4: агрегатные функции first_value, last_value, min_value, max_value с GROUP BY

Забудьте M4 — вот настоящие герои табличной модели: first_value, last_value, min_value, max_value. Они возвращают не только значение, но и timestamp, что критично для вашего желаемого результата. Ключ — комбинировать с GROUP BY ([start, end)), где интервал задаёт даунсемплинг.

Как это работает? first_value(value, ‘') берёт первую точку в окне, last_value — последнюю, min_value(time, value) — время и значение минимума. Для вашего окна 3000 мс: GROUP BY ([0ms, 3000ms)). Функция min_value(value, '’) игнорирует time в первом аргументе, если нужно только значение.

А если окна скользящие? Используйте SESSION или date_bin(‘3s’, time). В документации функций есть примеры: эти агрегаты поддерживают ORDER BY time ASC по умолчанию. Плюс, в 2.0.5 добавили first_value с маской '*" для всех серий.

Но есть нюанс: для нескольких окон нужно несколько GROUP BY или UNION. Или новая equal_size_bucket_m4_sample(value, ‘proportion’=‘0.1’) — прямой аналог M4 по бакетам равного размера. Тестируйте на своих данных — результат будет близок к древовидной модели.


Примеры SQL-запросов для даунсемплинга в iotdb 2.0.5 табличной модели

Давайте к делу. Ваш датасет в sensor_readings готов — time от 1000 до 6000, device=‘device01’, value от 10.0 до 18.0. Цель: четыре точки на окно 3000 мс, с timestamp.

Базовый запрос с фиксированным окном (аналог M4):

sql
SELECT
 first_value(time, '*') AS F_time, first_value(value, '*') AS F,
 last_value(time, '*') AS L_time, last_value(value, '*') AS L,
 min_value(time, value) AS M_time, min_value(value, '*') AS M,
 max_value(time, value) AS H_time, max_value(value, '*') AS H
FROM sensor_readings
WHERE device = 'device01'
GROUP BY ([0ms, 3000ms)), ([3000ms, 6000ms)), ([6000ms, 9000ms));

Ожидаемый вывод (примерно как в tree):

Time F_time F L_time L M_time M H_time H
1000 1000 10.0 3000 12.0 1000 10.0 2000 15.0

Первое окно [0-3000): F=10@1000, L=12@3000, M=10@1000, H=15@2000. Идеально!

С date_bin для скользящих окон (3 секунды):

sql
SELECT
 date_bin('3000ms', time) AS window_start,
 first_value(value) AS F,
 last_value(value) AS L,
 min_value(value) AS M,
 max_value(value) AS H
FROM sensor_readings
WHERE device = 'device01'
GROUP BY date_bin('3000ms', time);

Это проще, но без отдельных timestamp для M/H — доработайте min_value(time, value).

Бонус: equal_size_bucket_m4_sample (если доступно в вашей сборке):

sql
SELECT equal_size_bucket_m4_sample(value, 'proportion'='1.0', 'bucketSize'='3000') FROM sensor_readings WHERE device='device01';

Проверьте в IoTDB CLI — эти запросы воспроизводят ваш сценарий без ошибок. Если окон много, добавьте LIMIT или ORDER BY window_start.


Новые функции в apache iotdb 2.0.5: window functions и улучшения для table model

Apache IoTDB 2.0.5 — прорыв для table model: Dual-Model позволяет смешивать tree и table, плюс window functions вроде LAG, LEAD для даунсемплинга. История релизов хвалит tree-to-table views и расширенные агрегаты.

На GitHub в репозитории apache/iotdb коммиты вроде PR #13804 добавили first/last/min/max_by для таблиц. IT-тесты подтверждают: GROUP BY date_bin(‘5s’, time), min_by(time, value). Теперь JOIN с WHERE по тегам — норма.

Что это даёт? Прореживание данных быстрее, с FILL для пропусков. Если M4 добавят — следите за 2.1.x. А пока агрегаты рулят.


База данных временных рядов это: советы по выбору модели для IoT

База данных временных рядов вроде IoTDB — это не просто хранилище, а машина для IoT: сжатие, даунсемплинг, запросы на петабайты данных. Tree model хороша для простых сенсоров, table — для сложного анализа с тегами (device, location).

Совет: для вашего случая комбинируйте — пишите в table, читайте из tree-view. Масштаб? IoTDB жрёт мало RAM, но тестируйте GROUP BY на миллиардах точек. Вопрос: а зачем вам именно M4? Агрегаты гибче.

Переходите на table — будущее за ней.


Источники

  1. Stack Overflow — Вопрос о реализации даунсемплинга аналогичного M4 в табличной модели IoTDB: https://stackoverflow.com/questions/79876830/how-to-achieve-data-downsampling-similar-to-the-m4-function-in-apache-iotdbs-ta
  2. IoTDB Function and Expression — Документация по SQL-функциям, агрегатам и отсутствию M4 в table model: https://iotdb.apache.org/UserGuide/latest/SQL-Manual/Function-and-Expression.html
  3. IoTDB Release History — Нововведения в Apache IoTDB 2.0.5, включая Dual-Model и window functions: https://iotdb.apache.org/UserGuide/latest/IoTDB-Introduction/Release-history_apache.html
  4. IoTDB Table Model Queries — Руководство по запросам, GROUP BY и date_bin в табличной модели: https://iotdb.apache.org/UserGuide/latest-Table/Basic-Concept/Query-Data.html
  5. Apache IoTDB GitHub — Коммиты и тесты по агрегатам first/min/max для даунсемплинга: https://github.com/apache/iotdb

Заключение

Прореживание данных в табличной модели Apache IoTDB 2.0.5 без M4 — это не проблема, а возможность освоить мощные агрегаты first_value, last_value, min_value, max_value с GROUP BY. SQL-примеры выше дадут точный даунсемплинг для sensor_readings, сохраняя timestamp и ключевые точки. Следите за обновлениями — IoTDB эволюционирует, и table model станет ещё круче. Тестируйте, оптимизируйте — ваши IoT-данные заслуживают лучшего.

Yangyang Xun / Специалист по базам данных временных рядов

Функция M4 в Apache IoTDB предназначена для даунсемплинга (прореживания данных) временных рядов в древовидной модели, извлекая first (F), last (L), min (M) и max (H) из каждого временного окна.

В табличной модели IoTDB 2.0.5 возникает ошибка «Unknown function: m4».

Пользователь предоставил воспроизводимые данные для таблицы sensor_readings (device tag, value DOUBLE) и ищет SQL-альтернативы с сохранением timestamp для базы данных временных рядов.

В Apache IoTDB функция M4 доступна только в древовидной модели и не поддерживается в табличной — отсюда ошибка «unknown function».

Для даунсемплинга используйте агрегатные функции:

sql
SELECT first_value(value) AS F, last_value(value) AS L, min_value(value) AS M, max_value(value) AS H
FROM sensor_readings
GROUP BY [0, 3000) WHERE device='device01';

Альтернатива — equal_size_bucket_m4_sample(value, 'proportion'='0.1') для бакетов в IoTDB.

В Apache IoTDB 2.0.5 добавлена поддержка Dual-Model (tree-table), window functions и агрегатов first, last, min, max для табличной модели.

Это позволяет реализовать даунсемплинг без M4 через GROUP BY и стандартный SQL в базе данных временных рядов.

Релиз включает tree-to-table view и JOIN для IoT-данных.

@apache / Организация-разработчик ПО

Репозиторий Apache IoTDB на GitHub подтверждает добавление агрегатов max, min, first, last для табличной модели (PR #13804, #13835).

IT-тесты показывают GROUP BY date_bin(5s, time), min_by(time, s1) для прореживания данных.

Это решает проблему даунсемплинга в IoTDB 2.0.5 без M4, с поддержкой SELECT, WHERE, JOIN в table model.

В табличной модели IoTDB используйте date_bin_gapfill(1s, TIME), first(temperature) с GROUP BY для даунсемплинга.

Поддержка aligning sequences, FILL и JOIN позволяет извлекать ключевые точки (min, max) по окнам, аналогично M4 в древовидной модели Apache IoTDB.

Примените к таблице sensor_readings с окном 3000ms.

Авторы
Yangyang Xun / Специалист по базам данных временных рядов
Специалист по базам данных временных рядов
@apache / Организация-разработчик ПО
Организация-разработчик ПО
Источники
Портал документации
Проверено модерацией
Модерация
Даунсемплинг аналог M4 в табличной модели Apache IoTDB 2.0.5