FT.AGGREGATE

语法
FT.AGGREGATE index query 
  [VERBATIM] 
  [LOAD count field [field ...]] 
  [TIMEOUT timeout] 
  [ GROUPBY nargs property [property ...] [ REDUCE function nargs arg [arg ...] [AS name] [ REDUCE function nargs arg [arg ...] [AS name] ...]] ...]] 
  [ SORTBY nargs [ property ASC | DESC [ property ASC | DESC ...]] [MAX num] [WITHCOUNT] 
  [ APPLY expression AS name [ APPLY expression AS name ...]] 
  [ LIMIT offset num] 
  [FILTER filter] 
  [ WITHCURSOR [COUNT read_size] [MAXIDLE idle_time]] 
  [ PARAMS nargs name value [ name value ...]] 
  [SCORER scorer]
  [ADDSCORES] 
  [DIALECT dialect]
可用版本
Redis 开源版 / Search 1.1.0
时间复杂度
O(1)
ACL 类别
@search, @read, @fast,

在索引上运行搜索查询并对结果执行聚合转换。

注意
此命令仅返回用户具有读取权限的键。

示例

必需参数

index

是执行查询所针对的索引名称。必须先使用 FT.CREATE 创建索引。

query

是检索文档的基础过滤查询。它遵循与搜索查询完全相同的语法,包括过滤器、联合、非、可选等等。

可选参数

VERBATIM

如果设置,则不尝试使用词干提取进行查询扩展,而是按原样搜索查询词条。

LOAD {nargs} {identifier} AS {property} …

从源文档加载文档属性。

  • identifier 是哈希和 JSON 的属性名称,或者是 JSON 的 JSON Path 表达式。
  • property 是结果中使用的可选名称。如果未提供,则使用 identifier。应避免这种情况。
  • 如果使用 * 作为 nargs,则加载文档中的所有属性。

聚合所需的属性应存储为 SORTABLE,以便以非常低的延迟供聚合管道使用。LOAD 会显著影响聚合查询的性能,因为每个处理的记录都需要对 Redis 键执行等同于 HMGET 的操作,当对数百万个键执行此操作时,会导致较高的处理时间。

GROUPBY {nargs} {property}

根据一个或多个属性对管道中的结果进行分组。每个组应至少有一个 reducer,这是一个处理组条目的函数,可以计算它们,或执行多个聚合操作(参见下文)。

REDUCE {func} {nargs} {arg} … [AS {name}]

使用一个归约函数将每个组中匹配的结果归约到一个记录中。例如,COUNT 计算组中的记录数。可以使用可选参数 AS {name} 为归约器指定自己的属性名称。如果未指定名称,则结果名称将是归约函数的名称和组属性。例如,如果未通过属性 @fooCOUNT_DISTINCT 指定名称,则结果名称将为 count_distinct(@foo)

有关更多详细信息,请参见支持的 GROUPBY 归约器

SORTBY {nargs} {property} {ASC|DESC} [MAX {num}]

使用属性列表对管道进行排序,直至 SORTBY 点。

  • 默认情况下,排序是升序,但可以为每个属性添加 ASCDESC
  • nargs 是排序参数的数量,包括 ASCDESC,例如,SORTBY 4 @foo ASC @bar DESC
  • MAX 用于优化排序,只对最大的 n 个元素进行排序。虽然它与 LIMIT 无关,但通常只需要 SORTBY … MAX 来满足常见的查询。

SORTBY 所需的属性应存储为 SORTABLE,以便以非常低的延迟可用。

排序优化:在不同场景下,对 DIALECT 4 的排序操作进行了性能优化

  • 跳过排序器 - 在没有任何排序时应用。查询可以在达到请求的 LIMIT 结果后返回。
  • 部分范围 - 在数值字段上有 SORTBY 子句,且没有过滤器或按相同数值字段过滤时应用,查询会在足够大的范围内迭代以满足请求的 LIMIT 结果。
  • 混合 - 在数值字段上有 SORTBY 子句,并且还有另一个非数值过滤器时应用。一些结果会被过滤掉,初始范围可能不够大。然后迭代器会用后续范围重新开始,并进行额外的迭代来收集请求的 LIMIT 结果。
  • 未优化 - 如果按分数或非数值字段排序,则别无选择,只能检索所有结果并比较它们的值。

计数行为:可选的 WITHCOUNT 参数返回排序后查询结果的精确计数。此操作会处理所有结果以获取精确计数,性能低于优化选项(DIALECT 4 上的默认行为)。

APPLY {expr} AS {name}

对一个或多个属性应用一对一转换,并将结果作为新属性存储在管道中,或使用此转换替换任何属性。

expr 是一个表达式,可用于对数值属性执行算术运算,或对根据属性类型(参见下文)可应用于属性的函数,或它们的任何组合。例如,APPLY "sqrt(@foo)/log(@bar) + 5" AS baz 会为管道中的每个记录动态评估此表达式,并将结果存储为一个名为 baz 的新属性,该属性可供管道中后续的 APPLY/SORTBY/GROUPBY/REDUCE 操作引用。

有关详细信息,请参见APPLY 表达式

LIMIT {offset} {num}

将返回结果数限制为从索引 offset(从零开始)开始的 num 个结果。如果只想限制排序操作的输出,使用 SORTBY … MAX 会效率更高。如果在查询期间键过期,尝试 load 键的值将返回一个空数组。

但是,limit 可用于在不排序的情况下限制结果,或用于对由 SORTBY MAX 确定的 n 个最大结果进行分页。例如,获取前 100 个结果中的结果 50-100 最有效的表达方式是 SORTBY 1 @foo MAX 100 LIMIT 50 50。从 SORTBY 中删除 MAX 会导致管道对 所有 记录进行排序,然后对结果 50-100 进行分页。

FILTER {expr}

使用与每个结果中的值相关的谓词表达式过滤结果。它们在查询后应用,并与管道的当前状态相关。

WITHCURSOR {COUNT} {read_size} [MAXIDLE {idle_time}]

使用比 LIMIT 更快的替代方法扫描部分结果。有关更多详细信息,请参见游标 API

TIMEOUT {milliseconds}

如果设置,则覆盖模块的超时参数。

PARAMS {nargs} {name} {value}

定义一个或多个值参数。每个参数都有一个名称和一个值。

您可以在 query 中通过 $ 符号后跟参数名来引用参数,例如 $user。搜索查询中对参数名的每个此类引用都会被相应的参数值替换。例如,使用参数定义 PARAMS 4 lon 29.69465 lat 34.95126,表达式 @loc:[$lon $lat 10 km] 将被评估为 @loc:[29.69465 34.95126 10 km]。您不能在查询字符串中不允许具体值的地方引用参数,例如在字段名中,例如 @loc。要使用 PARAMS,请将 DIALECT 设置为 2 或大于 2

SCORER {scorer}

使用内置用户提供的评分函数。

ADDSCORES

ADDSCORES 选项将全文评分值暴露给聚合管道。您可以在管道中使用 @__score,示例如下:

FT.AGGREGATE idx 'hello' ADDSCORES SORTBY 2 @__score DESC

DIALECT {dialect_version}

选择执行查询所使用的方言版本。如果未指定,查询将使用模块初始加载时或通过 FT.CONFIG SET 命令设置的默认方言版本执行。

返回值

FT.AGGREGATE 返回一个数组回复,其中每一行都是一个数组回复,代表一个聚合结果。位置 1整数回复不表示有效值。

返回多个值

请参阅 FT.SEARCH 中的返回多个值。可以在 FT.AGGREGATE 命令中将 DIALECT 指定为参数。如果未指定,则使用 DEFAULT_DIALECT,可以通过 FT.CONFIG SET 设置或在加载 redisearch 模块时作为参数传递。例如,对于以下文档和索引:

127.0.0.1:6379> JSON.SET doc:1 $ '[{"arr": [1, 2, 3]}, {"val": "hello"}, {"val": "world"}]'
OK
127.0.0.1:6379> FT.CREATE idx ON JSON PREFIX 1 doc: SCHEMA $..arr AS arr NUMERIC $..val AS val TEXT
OK

注意使用和不使用 DIALECT 3 的不同回复。

127.0.0.1:6379> FT.AGGREGATE idx * LOAD 2 arr val 
1) (integer) 1
2) 1) "arr"
   2) "[1,2,3]"
   3) "val"
   4) "hello"

127.0.0.1:6379> FT.AGGREGATE idx * LOAD 2 arr val DIALECT 3
1) (integer) 1
2) 1) "arr"
   2) "[[1,2,3]]"
   3) "val"
   4) "[\"hello\",\"world\"]"

复杂度

非确定性。取决于执行的查询和聚合,但通常与返回的结果数量呈线性关系。

示例

按天对页面访问进行排序

查找对页面 about.html 的访问,按访问日期分组,计数访问次数,并按日期排序。

FT.AGGREGATE idx "@url:\"about.html\""
    APPLY "day(@timestamp)" AS day
    GROUPBY 2 @day @country
      REDUCE count 0 AS num_visits
    SORTBY 4 @day
查找出版书籍最多的一年

查找单年出版书籍最多的一年。

FT.AGGREGATE books-idx *
    GROUPBY 1 @published_year
      REDUCE COUNT 0 AS num_published
    GROUPBY 0
      REDUCE MAX 1 @num_published AS max_books_published_per_year
归约所有结果

上一个示例使用了 GROUPBY 0。使用 GROUPBY 0REDUCE 函数应用于聚合管道最后一步的所有结果——这适用于初始查询和后续的 GROUPBY 操作。

搜索经度 -73.982254 和纬度 40.753181 附近 10 公里内的图书馆,然后用它们的位置与这些坐标之间的距离来标注。

 FT.AGGREGATE libraries-idx "@location:[-73.982254 40.753181 10 km]"
    LOAD 1 @location
    APPLY "geodistance(@location, -73.982254, 40.753181)"

这里请注意必需使用 LOAD 来预加载 @location 属性,因为它是一个 GEO 属性。

接下来,按用户(actor)统计 GitHub 事件,找出最活跃的用户。

127.0.0.1:6379> FT.AGGREGATE gh "*" GROUPBY 1 @actor REDUCE COUNT 0 AS num SORTBY 2 @num DESC MAX 10
 1) (integer) 284784
 2) 1) "actor"
    2) "lombiqbot"
    3) "num"
    4) "22197"
 3) 1) "actor"
    2) "codepipeline-test"
    3) "num"
    4) "17746"
 4) 1) "actor"
    2) "direwolf-github"
    3) "num"
    4) "10683"
 5) 1) "actor"
    2) "ogate"
    3) "num"
    4) "6449"
 6) 1) "actor"
    2) "openlocalizationtest"
    3) "num"
    4) "4759"
 7) 1) "actor"
    2) "digimatic"
    3) "num"
    4) "3809"
 8) 1) "actor"
    2) "gugod"
    3) "num"
    4) "3512"
 9) 1) "actor"
    2) "xdzou"
    3) "num"
    4) "3216"
[10](10)) 1) "actor"
    2) "opstest"
    3) "num"
    4) "2863"
11) 1) "actor"
    2) "jikker"
    3) "num"
    4) "2794"
(0.59s)

另请参阅

FT.CONFIG SET | FT.SEARCH


评价此页面
返回顶部 ↑