*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 分批获取,避免单次返回过多数据导致内存或网络问题。