5 minutos
Melhores Práticas para um Subgraph #5 — Simplifique e Otimize com Séries Temporais e Agregações
TLDR
Leveraging the new time-series and aggregations feature in Subgraphs can significantly enhance both indexing speed and query performance.
Visão geral
Séries temporais e agregações reduzem a sobrecarga do processamento de dados e aceleram queries, ao descarregar computações de agregação para o banco de dados e simplificar o código de mapeamento. Essa abordagem é particularmente eficaz ao lidar com grandes volumes de dados baseados em tempo.
Vantagens de Séries Temporais e Agregações
- Indexação Mais Rápida
- Menos Dados para Carregar: Os mapeamentos manuseiam menos dados, pois os pontos de dados brutos são armazenados como entidades imutáveis de séries temporais.
- Agregações Geridas pelo Banco de Dados: As agregações são computadas automaticamente pelo banco de dados, reduzindo a carga de trabalho nos mapeamentos.
- Código de Mapeamentos Simplificado
- Sem Cálculos Manuais: os programadores não precisam mais escrever lógica complexa de agregação em mapeamentos.
- Complexidade Reduzida: Simplifica a manutenção de código e minimiza o potencial de erros.
- Queries Muito Mais Rápidos
- Dados Imutáveis: Todos os dados de séries temporais são imutáveis, deixando o armazenamento e resgate de dados muito mais eficiente.
- Separação de Dados Eficiente: Os dados agregados são armazenados separadamente dos brutos de séries temporais, permitindo que os queries processem muito menos dados — geralmente várias ordens de magnitude a menos.
Considerações Importantes
- Dados Imutáveis: os dados de séries temporais não podem ser alterados após gravados, garantindo a integridade e simplificando a indexação.
- Gestão Automática de ID e Registos de Tempo: os campos de ID, e de registo de data e hora, são administrados automaticamente pelo graph-node, reduzindo possíveis erros.
- Armazenamento Eficiente: ao separar dados brutos dos agregados, o armazenamento é otimizado e queries são executados mais rapidamente.
Como Implementar Séries Temporais e Agregações
Pré-requisitos
You need spec version 1.1.0
for this feature.
Como Definir Entidades de Séries Temporais
Uma entidade de série temporal representa pontos de dados brutos coletados gradativamente. Ela é definida com a anotação @entity(timeseries: true)
. Requisitos principais:
- Imutável: Entidades de série temporal são sempre imutáveis.
- Campos Obrigatórios:
id
: Deve ser do tipoInt8!
e é automaticamente incrementada.timestamp
: Deve ser do tipoTimestamp!
e é automaticamente configurada no registro de data e hora do bloco.
Exemplo:
1type Data @entity(timeseries: true) {2 id: Int8!3 timestamp: Timestamp!4 amount: BigDecimal!5}
Como Definir Entidades de Agregação
Uma entidade de agregação calcula valores agregados de uma fonte de série temporal. Ela é definida com a anotação @aggregation
. Componentes principais:
- Argumentos de Anotação:
intervals
: Especifica intervalos de tempo (por exemplo:["hour", "day"]
).
Exemplo:
1type Stats @aggregation(intervals: ["hour", "day"], source: "Data") {2 id: Int8!3 timestamp: Timestamp!4 sum: BigDecimal! @aggregate(fn: "sum", arg: "amount")5}
In this example, Stats aggregates the amount field from Data over hourly and daily intervals, computing the sum.
Queries de Dados Agregados
As agregações são expostas via campos de query que permitem filtragem e resgate com base em dimensões e intervalos de tempo.
Exemplo:
1{2 tokenStats(3 interval: "hour"4 where: { token: "0x1234567890abcdef", timestamp_gte: "1704164640000000", timestamp_lt: "1704251040000000" }5 ) {6 id7 timestamp8 token {9 id10 }11 totalVolume12 priceUSD13 count14 }15}
Como Usar Dimensões em Agregações
Dimensões são campos não agregados, usados para agrupar pontos de dados. Elas permitem agregações com base em critérios específicos, como um token num aplicativo financeiro.
Exemplo:
Entidade de Série Temporal
1type TokenData @entity(timeseries: true) {2 id: Int8!3 timestamp: Timestamp!4 token: Token!5 amount: BigDecimal!6 priceUSD: BigDecimal!7}
Entidade de Agregação com Dimensão
1type TokenStats @aggregation(intervals: ["hour", "day"], source: "TokenData") {2 id: Int8!3 timestamp: Timestamp!4 token: Token!5 totalVolume: BigDecimal! @aggregate(fn: "sum", arg: "amount")6 priceUSD: BigDecimal! @aggregate(fn: "last", arg: "priceUSD")7 count: Int8! @aggregate(fn: "count", cumulative: true)8}
- Campo de Dimensão:
token
agrupa os dados, então os agregados são computados por token. - Dados Agregados:
- totalVolume: Soma da quantia.
- priceUSD: último
priceUSD
(preço em dólares americanos) registrado. - count: Contagem cumulativa dos registos.
Funções e Expressões de Agregação
Funções de agregação apoiadas:
- sum (“Soma”)
- count (“Contagem”)
- min (“Mínimo”)
- max (“Máximo”)
- first (“Primeiro”)
- last (“Último”)
O argumento em @aggregate pode ser
- Um nome de campo da entidade de série temporal.
- Uma expressão com campos e constantes.
Exemplos de Expressões de Agregação
- Soma do Valor do Token: @aggregate(fn: “sum”, arg: “priceUSD _ amount”)
- Quantia Positiva Máxima: @aggregate(fn: “max”, arg: “greatest(amount0, amount1, 0)”)
- Soma Condicional: @aggregate(fn: “sum”, arg: “case when amount0 > amount1 then amount0 else 0 end”)
Os operadores e funções suportados incluem aritmética básica (+, -, _, /), operadores de comparação, operadores lógicos (and
, or
, not
) e funções SQL como least
, greatest
, coalesce
, etc.
Parâmetros de Query
interval
: Especifica intervalos de tempo (por exemplo: “hour”).where
: Aplica filtros com base em dimensões e alcance de tempo.timestamp_gte
/timestamp_lt:
Aplica filtros para início e fim de tempo (microssegundos desde o epoch).
Notas
- Classificação: Os resultados são automaticamente organizados por data e hora, e id, em ordem descendente.
- Dados Atuais: Um argumento atual opcional pode incluir o intervalo corrente, parcialmente preenchido.
Conclusão
Implementing timeseries and aggregations in Subgraphs is a best practice for projects dealing with time-based data. This approach:
- Melhora o Desempenho: Acelera a indexação e os queries ao reduzir a carga de processamento de dados.
- Simplifica a Produção: Elimina a necessidade de lógica de agregação manual em mapeamentos.
- Escala Eficientemente: Manuseia grandes quantias de dados sem comprometer a velocidade ou a capacidade de resposta.
By adopting this pattern, developers can build more efficient and scalable Subgraphs, providing faster and more reliable data access to end-users. To learn more about implementing timeseries and aggregations, refer to the Timeseries and Aggregations Readme and consider experimenting with this feature in your Subgraphs.