*Redis FT.AGGREGATE 命令
FT.AGGREGATE 对 RediSearch 索引执行聚合查询,支持分组、排序、统计、投影等操作。
*语法
FT.AGGREGATE index query
[LOAD field [field ...]]
[GROUPBY field [REDUCE func AS name ...]]
[SORTBY field [ASC|DESC] [MAX num]]
[LIMIT offset num]
[FILTER expr]
[APPLY expr AS name]
[WITHCURSOR [COUNT read_size] [MAXIDLE ms]]
[TIMEOUT ms]
[PARAMS name value [name value ...]]
[DIALECT dialect]
*参数说明
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| index | String | 是 | 索引名称 |
| query | String | 是 | 查询字符串,* 表示全部文档 |
| LOAD | Keyword | 否 | 加载指定字段到结果集 |
| GROUPBY | Keyword | 否 | 按字段分组 |
| REDUCE | Keyword | 否 | 聚合函数(COUNT、SUM、AVG、MIN、MAX、COUNT_DISTINCT 等) |
| SORTBY | Keyword | 否 | 排序字段及方向 |
| LIMIT | Keyword | 否 | 分页,offset 起始位置,num 返回数量 |
| FILTER | Keyword | 否 | 对结果行进行过滤(表达式) |
| APPLY | Keyword | 否 | 计算表达式并将结果作为新字段 |
| WITHCURSOR | Keyword | 否 | 使用游标返回结果 |
| TIMEOUT | Integer | 否 | 超时时间(毫秒) |
| PARAMS | Keyword | 否 | 查询参数替换(配合 $param 语法) |
| DIALECT | Integer | 否 | 查询语法版本(1 或 2) |
*返回值
- Array:聚合结果数组,第一行为字段名,后续为数据行
*时间复杂度
取决于查询复杂度和数据量。简单聚合 O(N),N 为匹配文档数。
*示例
*基本统计
> FT.AGGREGATE idx:products "*" GROUPBY 0 REDUCE COUNT 0 AS total
1) "total"
2) "1000"
*按类别分组统计
> FT.AGGREGATE idx:products "*" GROUPBY 1 @category REDUCE COUNT 0 AS count
1) "category"
2) " Electronics"
3) "count"
4) "450"
5) "category"
6) " Clothing"
7) "count"
8) "300"
*排序和分页
> FT.AGGREGATE idx:products "*" GROUPBY 1 @brand REDUCE COUNT 0 AS count SORTBY 1 @count DESC LIMIT 0 10
*加载字段并应用表达式
> FT.AGGREGATE idx:products "*" LOAD 1 @price APPLY "@price * 0.8" AS discounted_price
*常见错误
| 错误 | 原因 | 解决 |
|---|---|---|
| Index not found | 索引不存在 | 检查索引名称,先用 FT._LIST 确认 |
| Syntax error | 查询语法错误 | 检查 GROUPBY、REDUCE 语法 |
| DIALECT 1 syntax error | 使用了 DIALECT 2 特性 | 指定 DIALECT 2 |
*最佳实践
- 大数据量聚合使用
WITHCURSOR避免内存溢出 - 使用 DIALECT 2 获得更现代的查询语法支持
- 尽量在 FT.CREATE 时定义 SORTABLE 字段以提升排序性能
- 复杂表达式使用
PARAMS参数化防止注入
*FAQ
Q1: FT.AGGREGATE 和 FT.SEARCH 有什么区别? A: FT.SEARCH 返回完整文档内容;FT.AGGREGATE 专注于数据聚合,可分组、统计、计算,不返回原始文档(除非 LOAD)。
Q2: 支持哪些 REDUCE 函数? A: COUNT、SUM、AVG、MIN、MAX、COUNTDISTINCT、COUNTDISTINCTISH、STDDEV、QUANTILE、TOLIST、FIRSTVALUE、RANDOMSAMPLE 等。
Q3: 聚合结果可以排序后再限制数量吗? A: 可以,使用 SORTBY + LIMIT 组合,但 LIMIT 在聚合管道中的位置影响执行顺序。
Q4: 如何处理大量聚合结果? A: 使用 WITHCURSOR 分批获取,避免单次返回过多数据导致内存或网络问题。