Overview
DirectAggregate allows you to aggregate data that isn’t stored in a Convex table. You manually insert, delete, and replace items in the aggregate data structure. This is useful for:- Collecting statistics or metrics that don’t need persistent storage
- Aggregating ephemeral data
- Building custom data structures with aggregation capabilities
Creating a DirectAggregate
Define a DirectAggregate with type parameters for the key and ID:Type Parameters
- Key: The type used to sort items (can be number, string, array, etc.)
- Id: A unique string identifier for each item
- Namespace (optional): Type for partitioning data into separate namespaces
Basic Operations
Insert
Add a new item to the aggregate. The ID must be unique:[key, id] pair already exists, this will throw an error.
Delete
Remove an item from the aggregate:Replace
Update an existing item atomically:Idempotent Operations
For migrations and backfills, use idempotent versions that don’t throw errors:insertIfDoesNotExist
deleteIfExists
replaceOrInsert
Statistics Example
Here’s a complete example tracking latency statistics:Using Namespaces
Partition data into separate namespaces for independent aggregation:Querying DirectAggregates
DirectAggregate supports all the same query methods as TableAggregate:When to Use DirectAggregate
Choose DirectAggregate over TableAggregate when:- No persistent storage needed: You’re collecting temporary metrics or statistics
- Custom key generation: Your keys don’t correspond to document fields
- Non-table data sources: Aggregating data from external APIs or computed values
- Full control: You want explicit control over insert/delete/replace timing
- You’re aggregating data from a Convex table
- You want automatic updates via triggers
- Keys and sum values come directly from document fields
Next Steps
- Improve performance with Batch Operations
- Learn about Keeping Data in Sync
- Understand Migrations and Backfills