4 minutes
Лучшие практики субграфов №5 — Упрощение и оптимизация с помощью временных рядов и агрегаций
Краткое содержание
Использование новой функции временных рядов и агрегаций в субграфах может значительно улучшить как скорость индексирования, так и производительность запросов.
Обзор
Временные ряды и агрегации снижают накладные расходы на обработку данных и ускоряют запросы, перенося вычисления агрегаций на базу данных и упрощая код отображений. Этот подход особенно эффективен при обработке больших объемов данных, основанных на времени.
Преимущества временных рядов и агрегаций
- Улучшенное время индексирования
- Меньше данных для загрузки: мэппинги обрабатывают меньше данных, поскольку необработанные данные хранятся в виде неизменяемых объектов временных рядов.
- Агрегации, управляемые базой данных: агрегации вычисляются автоматически базой данных, что снижает нагрузку на мэппинги.
- Упрощённый код мэппинга
- Отсутствие ручных вычислений: разработчикам больше не нужно писать сложную логику агрегации в мэппингах.
- Снижение сложности: упрощает обслуживание кода и минимизирует вероятность ошибок.
- Существенное ускорение запросов
- Неизменяемые данные: все данные временных рядов неизменяемы, что обеспечивает эффективное хранение и извлечение.
- Эффективное разделение данных: агрегаты хранятся отдельно от необработанных данных временных рядов, что позволяет запросам обрабатывать значительно меньше данных — часто на несколько порядков меньше.
Важные замечания
- Незаменяемость данных: данные временных рядов не могут быть изменены после записи, что обеспечивает целостность данных и упрощает индексирование.
- Автоматическое управление ID и метками времени: поля id и timestamp автоматически управляются graph-node, что снижает вероятность ошибок.
- Эффективное хранение данных: разделение необработанных данных и агрегатов оптимизирует хранилище и ускоряет выполнение запросов.
Как внедрить временные ряды и агрегации
Определение объектов временных рядов
Объект временного ряда представляет собой необработанные данные, собранные с течением времени. Он определяется с помощью аннотации @entity(timeseries: true)
. Ключевые требования:
- Неизменяемость: объекты временного ряда всегда неизменяемы.
- Обязательные поля:
id
: должен быть типаInt8!
и автоматически увеличиваться.timestamp
: должен быть типаTimestamp!
и автоматически устанавливаться в соответствии с временной меткой блока.
Пример:
type Data @entity(timeseries: true) { id: Int8! timestamp: Timestamp! price: BigDecimal!}
Определение объектов агрегаций
Объект агрегации вычисляет агрегированные значения из источника данных временного ряда. Он определяется с помощью аннотации @aggregation
. Ключевые компоненты:
- Аргументы аннотации:
intervals
: указывает временные интервалы (например,["hour", "day"]
).
Пример:
type Stats @aggregation(intervals: ["hour", "day"], source: "Data") { id: Int8! timestamp: Timestamp! sum: BigDecimal! @aggregate(fn: "sum", arg: "price")}
В этом примере статистика агрегирует поле цены из данных за часовые и дневные интервалы, вычисляя сумму.
Запрос агрегированных данных
Агрегации предоставляются через поля запросов, которые позволяют фильтровать и извлекать данные на основе измерений и временных интервалов.
Пример:
{ tokenStats( interval: "hour" where: { token: "0x1234567890abcdef", timestamp_gte: "1704164640000000", timestamp_lt: "1704251040000000" } ) { id timestamp token { id } totalVolume priceUSD count }}
Использование измерений в агрегациях
Измерения — это неагрегированные поля, которые используются для группировки точек данных. Они позволяют выполнять агрегации на основе определённых критериев, таких как токен в финансовом приложении.
Пример:
Объект временного ряда
type TokenData @entity(timeseries: true) { id: Int8! timestamp: Timestamp! token: Token! amount: BigDecimal! priceUSD: BigDecimal!}
Объект агрегации с измерением
type TokenStats @aggregation(intervals: ["hour", "day"], source: "TokenData") { id: Int8! timestamp: Timestamp! token: Token! totalVolume: BigDecimal! @aggregate(fn: "sum", arg: "amount") priceUSD: BigDecimal! @aggregate(fn: "last", arg: "priceUSD") count: Int8! @aggregate(fn: "count", cumulative: true)}
- Поле измерения:
token
группирует данные, так что агрегированные значения вычисляются для каждого токена. - Агрегаты:
- totalVolume: сумма количества.
- priceUSD: последняя зафиксированная цена в USD.
- count: кумулятивное количество записей.
Функции агрегации и выражения
Поддерживаемые функции агрегации:
- sum
- count
- min
- max
- first
- last
Аргумент в @aggregate
может быть
- Названием поля из объекта временных рядов.
- Выражением, использующим поля и константы.
Примеры выражений агрегации
- Сумма стоимости токена: @aggregate(fn: “sum”, arg: “priceUSD * amount”)
- Максимальное положительное значение суммы: @aggregate(fn: “max”, arg: “greatest(amount0, amount1, 0)”)
- Условная сумма: @aggregate(fn: “sum”, arg: “case when amount0 > amount1 then amount0 else 0 end”)
Поддерживаемые операторы и функции включают базовую арифметику (+, -, *, /), операторы сравнения, логические операторы (and, or, not), а также SQL-функции, такие как greatest, least, coalesce и другие.
Параметры запроса
- interval: указывает временной интервал (например, “час”).
- where: фильтрует данные по измерениям и диапазонам временных меток.
- timestamp_gte / timestamp_lt: фильтрует по времени начала и окончания (микросекунды с эпохи).
Примечания
- Сортировка: результаты автоматически сортируются по временным меткам и идентификатору в порядке убывания.
- Текущие данные: опциональный текущий аргумент может включать текущий, частично заполненный интервал.
Заключение
Внедрение временных рядов и агрегаций в субграфы является лучшей практикой для проектов, работающих с данными, зависящими от времени. Этот подход:
- Улучшает производительность: ускоряет индексирование и запросы, снижая нагрузку на обработку данных.
- Упрощает разработку: устраняет необходимость в ручном написании логики агрегации в мэппингах.
- Эффективно масштабируется: обрабатывает большие объемы данных, не ухудшая скорость и отзывчивость.
Применяя этот шаблон, разработчики могут создавать более эффективные и масштабируемые субграфы, обеспечивая более быстрый и надежный доступ к данным для конечных пользователей. Чтобы узнать больше о внедрении временных рядов и агрегаций, обратитесь к Руководству по временным рядам и агрегациям и рассмотрите возможность использования этой функции в своих субграфах.