fuel-indexer icon indicating copy to clipboard operation
fuel-indexer copied to clipboard

Add support for aggregate GraphQL queries

Open deekerno opened this issue 2 years ago • 1 comments

Aggregate queries allow for the return of statistical summaries of records that match certain criteria. For example, one may want to get the count of all transactions in the network. We could support the request with something like the following GraphQL query:

query {
  aggregateTransaction {
    count
  }
}

Additionally, we could allow for advanced aggregate queries by only allowing for certain inputs depending on the entity type and its fields. Here are a few example queries:

Get the average amount per transaction

query {
  aggregateTransaction {
    amountAvg
  }
}

Get the min, max, total, and average of all contract balances

query {
  aggregateContractBalance {
    amountMin
    amountMax
    amountSum
    amountAvg
  }
}

Here is some prior work from which we can take inspiration.

deekerno avatar Nov 21 '23 19:11 deekerno

@deekerno

  • This question is more so for my own understanding.
  • But would this implementation potentially be something as straighforward as:
aggregate$Entity {
  $field$Operation
}
  • Where (using your example(s)):
    • aggregate prefix denotes the user wants to perform an aggregation
    • $Entity is just the PascalCase entity name
    • $field is the camelCase field on the $Entity
    • $Operation is one value from some discrete set of operations (e.g., min, max, sum, avg, ...)

Am I thinking about this correctly?

  • Some other thoughts after looking at the link you referenced:
    • It looks like aggregate can either be a prefix? aggregateFoo or a suffix? fooAggregate
    • Also looks like an aggregate can accept a parameter that's a filter (so I'm thinking we could just re-use the filter logic from https://github.com/FuelLabs/fuel-indexer/pull/1450 ?)
    • Finally, when you give a field aggregate fooAggregate() { } the fact that it's an aggregation is implied by the field/node name (fooAggregate) thus you only need to name the reducer inside the node (e.g., fooAggregate() { count } )

ra0x3 avatar Nov 27 '23 15:11 ra0x3