|
| 1 | +--- |
| 2 | +categories: |
| 3 | +- docs |
| 4 | +- develop |
| 5 | +- stack |
| 6 | +- oss |
| 7 | +- rs |
| 8 | +- rc |
| 9 | +- oss |
| 10 | +- kubernetes |
| 11 | +- clients |
| 12 | +description: Order of operations for the FT.AGGREGATE command |
| 13 | +linkTitle: Aggregation syntax |
| 14 | +title: FT.AGGREGATE order of operations |
| 15 | +weight: 2 |
| 16 | +--- |
| 17 | + |
| 18 | +## Overview |
| 19 | + |
| 20 | +[`FT.AGGREGATE`]({{< relref "/commands/ft.aggregate" >}}) is a powerful command in RQE module for performing advanced data aggregation, filtering, sorting, and transformations on indexed documents. This reference page provides a structured breakdown of syntax, ordering rules, and best practices. |
| 21 | + |
| 22 | +## Syntax and expression ordering |
| 23 | + |
| 24 | +The `FT.AGGREGATE` command processes multiple expressions in a pipeline. Below is the recommended order: |
| 25 | + |
| 26 | +1. `FILTER` – filters raw documents before transformations or aggregation. |
| 27 | +1. `LOAD` – loads additional document attributes. |
| 28 | +1. `APPLY` – applies transformations on fields. |
| 29 | +1. `GROUPBY` – groups results by specific fields. |
| 30 | +1. `REDUCE` – performs aggregations. For example, `SUM`, `COUNT`, and `AVG`. |
| 31 | +1. `SORTBY` – orders the results based on specified fields. |
| 32 | +1. `LIMIT` – restricts the number of results returned. |
| 33 | + |
| 34 | +## Using GROUPBY with multiple REDUCE |
| 35 | + |
| 36 | +`GROUPBY` can be followed by multiple `REDUCE` operations for different aggregations. |
| 37 | +```sh |
| 38 | +FT.AGGREGATE products "*" |
| 39 | + GROUPBY 1 @category |
| 40 | + REDUCE COUNT 0 AS product_count |
| 41 | + REDUCE SUM 1 @price AS total_price |
| 42 | + REDUCE AVG 1 @rating AS avg_rating |
| 43 | + SORTBY 2 @total_price DESC |
| 44 | + LIMIT 0 10 |
| 45 | +``` |
| 46 | + |
| 47 | +## Using multiple APPLY, GROUPBY, and REDUCE |
| 48 | + |
| 49 | +`APPLY` can be used in various ways before and after `GROUPBY` and `REDUCE`. |
| 50 | +```sh |
| 51 | +FT.AGGREGATE products "*" |
| 52 | + APPLY "@price - @discount AS final_price" |
| 53 | + APPLY "@final_price * @quantity AS total_revenue" |
| 54 | + GROUPBY 1 @category |
| 55 | + REDUCE SUM 1 total_revenue AS total_category_revenue |
| 56 | + SORTBY 2 total_category_revenue DESC |
| 57 | + LIMIT 0 10 |
| 58 | +``` |
| 59 | + |
| 60 | +## Using FILTER and PARAMS |
| 61 | + |
| 62 | +`FILTER` is used to remove unwanted records, while `PARAMS` allows parameterized queries. |
| 63 | +```sh |
| 64 | +FT.AGGREGATE products "*" |
| 65 | + PARAMS 2 "min_price" 500 "min_rating" 4.0 |
| 66 | + FILTER "@price >= $min_price" |
| 67 | + FILTER "@rating >= $min_rating" |
| 68 | + APPLY "@price * @quantity AS total_value" |
| 69 | + SORTBY 2 total_value DESC |
| 70 | + LIMIT 0 10 |
| 71 | +``` |
| 72 | + |
| 73 | +## Placement of FILTER before and after GROUPBY/APPLY |
| 74 | + |
| 75 | +- **Before GROUPBY:** Removes records before aggregation. |
| 76 | +- **After GROUPBY:** Filters based on aggregated results. |
| 77 | +- **Before APPLY:** Ensures calculations are applied only to certain records. |
| 78 | +- **After APPLY:** Filters computed values. |
| 79 | + |
| 80 | +## Using LOAD after GROUPBY/REDUCE |
| 81 | + |
| 82 | +`LOAD` is generally used **before** `GROUPBY`, but in some cases, it can be used afterward to retrieve document metadata. |
| 83 | +```sh |
| 84 | +FT.AGGREGATE products "*" |
| 85 | + GROUPBY 1 @category |
| 86 | + REDUCE COUNT 0 AS product_count |
| 87 | + REDUCE SUM 1 @price AS total_price |
| 88 | + WITHCURSOR COUNT 5 |
| 89 | +``` |
| 90 | + |
| 91 | +## Placement rules for specific parameters |
| 92 | + |
| 93 | +| Parameter | Placement | |
| 94 | +|-----------|----------------| |
| 95 | +| `TIMEOUT` | Can be placed anywhere | |
| 96 | +| `LIMIT` | Must be at the end | |
| 97 | +| `WITHCURSOR` | Must be at the end | |
| 98 | +| `SCORER` | Can be placed anywhere | |
| 99 | +| `ADDSCORES` | Must be before sorting | |
| 100 | +| `DIALECT` | Must be at the end | |
| 101 | + |
| 102 | +## LIMIT and WITHCURSOR are mutually exclusive |
| 103 | + |
| 104 | +`LIMIT` returns immediate results, while `WITHCURSOR` retrieves results incrementally. |
| 105 | +```sh |
| 106 | +FT.AGGREGATE products "*" |
| 107 | + GROUPBY 1 @category |
| 108 | + REDUCE COUNT 0 AS product_count |
| 109 | + WITHCURSOR COUNT 5 |
| 110 | +``` |
| 111 | + |
| 112 | +## Summary |
| 113 | + |
| 114 | +- `GROUPBY` allows multiple `REDUCE` functions. |
| 115 | +- `APPLY` can be positioned before or after grouping. |
| 116 | +- `FILTER` placement affects results significantly. |
| 117 | +- `LOAD` after `GROUPBY` is only useful in specific cases. |
| 118 | +- `LIMIT` and `WITHCURSOR` **cannot** be used together. |
| 119 | + |
| 120 | +For further reference: |
| 121 | +- [`FT.AGGREGATE` command page](https://redis.io/docs/latest/commands/ft.aggregate/) |
| 122 | +- [RQE source code](https://github.com/RediSearch/RediSearch/tree/master/src/aggregate) |
| 123 | + |
0 commit comments