Даунсемплинг аналог M4 в табличной модели Apache IoTDB 2.0.5
Как реализовать прореживание данных (даунсемплинг) в Apache IoTDB табличной модели без функции M4. SQL-примеры с first_value, last_value, min_value, max_value и GROUP BY для извлечения ключевых точек временных рядов.
Как реализовать даунсемплинг данных, аналогичный функции M4, в табличной модели Apache IoTDB?
Я создал аналогичные наборы данных в древовидной модели и табличной модели Apache IoTDB 2.0.5. В древовидной модели функция M4 легко выполняет даунсемплинг временных рядов, извлекая четыре ключевые точки из каждого временного окна: первую точку (F), последнюю точку (L), минимум (M) и максимум (H). Однако при попытке выполнить то же самое в табличной модели возникает ошибка «unknown function».
Воспроизводимые данные и шаги
Древовидная модель
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 секунды (выполняется успешно):
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|
+-----------------------------+-------------------------------------------------------+
Табличная модель (проблема)
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 в табличной модели (неудача):
SELECT M4(value, 'timeInterval'='3000') FROM sensor_readings WHERE device='device01';
Сообщение об ошибке:
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 и почему она не работает в табличной модели
- Прореживание данных (даунсемплинг) во временных рядах: различия tree и table моделей apache iotdb
- Альтернативы M4: агрегатные функции first_value, last_value, min_value, max_value с GROUP BY
- Примеры SQL-запросов для даунсемплинга в iotdb 2.0.5 табличной модели
- Новые функции в apache iotdb 2.0.5: window functions и улучшения для table model
- База данных временных рядов это: советы по выбору модели для IoT
- Источники
- Заключение
Что такое функция 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):
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 секунды):
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 (если доступно в вашей сборке):
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 — будущее за ней.
Источники
- Stack Overflow — Вопрос о реализации даунсемплинга аналогичного M4 в табличной модели IoTDB: https://stackoverflow.com/questions/79876830/how-to-achieve-data-downsampling-similar-to-the-m4-function-in-apache-iotdbs-ta
- IoTDB Function and Expression — Документация по SQL-функциям, агрегатам и отсутствию M4 в table model: https://iotdb.apache.org/UserGuide/latest/SQL-Manual/Function-and-Expression.html
- IoTDB Release History — Нововведения в Apache IoTDB 2.0.5, включая Dual-Model и window functions: https://iotdb.apache.org/UserGuide/latest/IoTDB-Introduction/Release-history_apache.html
- IoTDB Table Model Queries — Руководство по запросам, GROUP BY и date_bin в табличной модели: https://iotdb.apache.org/UserGuide/latest-Table/Basic-Concept/Query-Data.html
- 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-данные заслуживают лучшего.
Функция 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».
Для даунсемплинга используйте агрегатные функции:
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 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.