Aggregate Table

https://{your-workspace-slug}.{region}.xata.sh/db/db_branch_name/tables/table_name/aggregate

Expected parameters

NameDescriptionInRequiredSchema
db_branch_name

The DBBranchName matches the pattern {db_name}:{branch_name}.

path✅string
table_name

The Table name

path✅string

Run Aggregations Over a Table

POST
https://{your-workspace-slug}.{region}.xata.sh/db/db_branch_name/tables/table_name/aggregate

This endpoint allows you to run aggregations (analytics) on the data from one table. While the summary endpoint is served from a transactional store and the results are strongly consistent, the aggregate endpoint is served from our columnar store and the results are only eventually consistent. On the other hand, the aggregate endpoint uses a store that is more appropiate for analytics, makes use of approximative algorithms (e.g for cardinality), and is generally faster and can do more complex aggregations.

For usage, see the API Guide.

Request Body Type Definition

type AggregateTable = {
    filter?: FilterExpression;
    aggs?: AggExpressionMap;
};
 
/**
 * @minProperties 1
 */
type FilterExpression = {
    $exists?: string;
    $existsNot?: string;
    $any?: FilterList;
    $all?: FilterList;
    $none?: FilterList;
    $not?: FilterList;
} & {
    [key: string]: FilterColumn;
};
 
/**
 * The description of the aggregations you wish to receive.
 * 
 * @example {"totalCount":{"count":"*"},"dailyActiveUsers":{"dateHistogram":{"column":"date","interval":"1d","aggs":{"uniqueUsers":{"uniqueCount":{"column":"userID"}}}}}}
 */
type AggExpressionMap = {
    [key: string]: AggExpression;
};
 
type FilterList = FilterExpression | FilterExpression[];
 
type FilterColumn = FilterColumnIncludes | FilterPredicate | FilterList;
 
/**
 * The description of a single aggregation operation. It is an object with only one key-value pair.
 * The key represents the aggregation type, while the value is an object with the configuration of
 * the aggregation.
 */
type AggExpression = {
    count?: CountAgg;
} | {
    sum?: SumAgg;
} | {
    max?: MaxAgg;
} | {
    min?: MinAgg;
} | {
    average?: AverageAgg;
} | {
    uniqueCount?: UniqueCountAgg;
} | {
    dateHistogram?: DateHistogramAgg;
} | {
    topValues?: TopValuesAgg;
} | {
    numericHistogram?: NumericHistogramAgg;
};
 
/**
 * @maxProperties 1
 * @minProperties 1
 */
type FilterColumnIncludes = {
    $includes?: FilterPredicate;
    $includesAny?: FilterPredicate;
    $includesAll?: FilterPredicate;
    $includesNone?: FilterPredicate;
};
 
type FilterPredicate = FilterValue | FilterPredicate[] | FilterPredicateOp | FilterPredicateRangeOp;
 
/**
 * Count the number of records with an optional filter.
 */
type CountAgg = {
    filter?: FilterExpression;
} | ("*");
 
/**
 * The sum of the numeric values in a particular column.
 */
type SumAgg = {
    /**
     * The column on which to compute the sum. Must be a numeric type.
     */
    column: string;
};
 
/**
 * The max of the numeric values in a particular column.
 */
type MaxAgg = {
    /**
     * The column on which to compute the max. Must be a numeric type.
     */
    column: string;
};
 
/**
 * The min of the numeric values in a particular column.
 */
type MinAgg = {
    /**
     * The column on which to compute the min. Must be a numeric type.
     */
    column: string;
};
 
/**
 * The average of the numeric values in a particular column.
 */
type AverageAgg = {
    /**
     * The column on which to compute the average. Must be a numeric type.
     */
    column: string;
};
 
/**
 * Count the number of distinct values in a particular column.
 */
type UniqueCountAgg = {
    /**
     * The column from where to count the unique values.
     */
    column: string;
    /**
     * The threshold under which the unique count is exact. If the number of unique
     * values in the column is higher than this threshold, the results are approximate.
     * Maximum value is 40,000, default value is 3000.
     */
    precisionThreshold?: number;
};
 
/**
 * Split data into buckets by a datetime column. Accepts sub-aggregations for each bucket.
 */
type DateHistogramAgg = {
    /**
     * The column to use for bucketing. Must be of type datetime.
     */
    column: string;
    /**
     * The fixed interval to use when bucketing.
     * It is formatted as number + units, for example: `5d`, `20m`, `10s`.
     *
     * @pattern ^(\d+)(d|h|m|s|ms)$
     */
    interval?: string;
    /**
     * The calendar-aware interval to use when bucketing. Possible values are: `minute`,
     * `hour`, `day`, `week`, `month`, `quarter`, `year`.
     */
    calendarInterval?: "minute" | "hour" | "day" | "week" | "month" | "quarter" | "year";
    /**
     * The timezone to use for bucketing. By default, UTC is assumed.
     * The accepted format is as an ISO 8601 UTC offset. For example: `+01:00` or
     * `-08:00`.
     *
     * @pattern ^[+-][01]\d:[0-5]\d$
     */
    timezone?: string;
    aggs?: AggExpressionMap;
};
 
/**
 * Split data into buckets by the unique values in a column. Accepts sub-aggregations for each bucket.
 * The top values as ordered by the number of records (`$count`) are returned.
 */
type TopValuesAgg = {
    /**
     * The column to use for bucketing. Accepted types are `string`, `email`, `int`, `float`, or `bool`.
     */
    column: string;
    aggs?: AggExpressionMap;
    /**
     * The maximum number of unique values to return.
     *
     * @default 10
     * @maximum 1000
     */
    size?: number;
};
 
/**
 * Split data into buckets by dynamic numeric ranges. Accepts sub-aggregations for each bucket.
 */
type NumericHistogramAgg = {
    /**
     * The column to use for bucketing. Must be of numeric type.
     */
    column: string;
    /**
     * The numeric interval to use for bucketing. The resulting buckets will be ranges
     * with this value as size.
     *
     * @minimum 0
     */
    interval: number;
    /**
     * By default the bucket keys start with 0 and then continue in `interval` steps. The bucket
     * boundaries can be shifted by using the offset option. For example, if the `interval` is 100,
     * but you prefer the bucket boundaries to be `[50, 150), [150, 250), etc.`, you can set `offset`
     * to 50.
     *
     * @default 0
     */
    offset?: number;
    aggs?: AggExpressionMap;
};
 
type FilterValue = number | string | boolean;
 
/**
 * @maxProperties 1
 * @minProperties 1
 */
type FilterPredicateOp = {
    $any?: FilterPredicate[];
    $all?: FilterPredicate[];
    $none?: FilterPredicate | FilterPredicate[];
    $not?: FilterPredicate | FilterPredicate[];
    $is?: FilterValue | FilterValue[];
    $isNot?: FilterValue | FilterValue[];
    $lt?: FilterRangeValue;
    $le?: FilterRangeValue;
    $gt?: FilterRangeValue;
    $ge?: FilterRangeValue;
    $contains?: string;
    $startsWith?: string;
    $endsWith?: string;
    $pattern?: string;
};
 
/**
 * @maxProperties 2
 * @minProperties 2
 */
type FilterPredicateRangeOp = {
    $lt?: FilterRangeValue;
    $le?: FilterRangeValue;
    $gt?: FilterRangeValue;
    $ge?: FilterRangeValue;
};
 
type FilterRangeValue = number | string;

Responses

{
    "aggs": {
        "dailyUniqueUsers": {
            "values": [
                {
                    "$count": 321,
                    "$key": "2022-02-22T22:22:22Z",
                    "uniqueUsers": 134
                },
                {
                    "$count": 202,
                    "$key": "2022-02-23T22:22:22Z",
                    "uniqueUsers": 90
                }
            ]
        }
    }
}