RedisConf 的一项重要发布是 RediSearch (版本 1.1.0) 的聚合引擎。聚合对于像 RediSearch 这样的实时搜索引擎来说是一个极其强大的功能。它们不仅允许查询数据,还可以对数据进行数学汇总以获得分析洞察。RediSearch 聚合附带了一套标准的归约器(reducers):
从概念上讲,聚合由一系列操作组成的管道构成。每个操作可以按任何逻辑顺序使用,并且可以重复。基本操作包括:
例如,考虑一个电商场景中的发货数据,其中包含过去十年数百万次发货的时间戳和总箱子尺寸 (box_area)。假设您想找出箱子尺寸大于 300 的发货量排名前三的年份。我们不关心确切的数字;我们只想要一个大概的数值,并且希望格式美观。我们的聚合查询如下所示:
FT.AGGREGATE shipments "@box_area:[300 +inf]"
APPLY "year(@shipment_timestamp / 1000)" AS shipment_year
GROUPBY 1 @shipment_year REDUCE COUNT 0 AS shipment_count
SORTBY 2 @shipment_count DESC
LIMIT 0 3
APPLY "format(\"%sk+ Shipments\",floor(@shipment_count / 1000))" AS shipment_count
这看起来可能与您以前见过的任何 Redis 命令都不同,但拆解开来并不复杂。
FT.AGGREGATE shipments "@box_area:[300 +inf]" | 在索引“shipments”中,查找 box_area 大于 300 的项目。这使用了与 RediSearch 其余部分相同的查询语法。 |
APPLY "year(@shipment_timestamp)" AS shipment_year | 这将使用内置函数将 shipment_timestamp 转换为年份。现在可以通过 shipment_year 访问此结果。 |
GROUPBY 1 @shipment_year REDUCE COUNT 0 AS shipment_count | 将所有 shipment_year 结果分组并计数。将此结果命名为 shipment_count。 |
SORTBY 2 @shipment_count DESC | 我们将根据上一步计算出的计数按降序对这些值进行排序。 |
LIMIT 0 3 | 我们只关心前三个值。 |
APPLY "format("%sk+ Shipments",floor(@shipment_count / 1000))" AS shipment_count | 再次转换计数。从内部表达式(在 floor 中)开始,我们将进行一些算术运算以缩短数字,因为我们不关心精确值。然后我们将使用 floor 去除小数点后的任何部分。最后,我们将使用 printf 风格的格式对其进行格式化,并(再次)将其命名为 shipment_count。 |
这将输出以下结果
1) (integer) 10 2) 1) "shipment_year" 2) "2014" 3) "shipment_count" 4) "10k+ Shipments" 3) 1) "shipment_year" 2) "2017" 3) "shipment_count" 4) "9k+ Shipments" 4) 1) "shipment_year" 2) "2015" 3) "shipment_count" 4) "9k+ Shipments"
通过将这些操作组合在一起,您可以以前所未有的方式快速分析数据。这是一个非常深入和广泛的功能,仅凭这篇博客文章很难完全概括,因此最好通过实际操作来了解。观看此视频了解 Dvir 演示聚合功能
RedisConf 后不久,我们发布了 RediSearch 1.2.0 版本,其中包含一系列新功能
使子查询修改查询的子句。这允许实现:
~(ice cream sandwich) => { $weight: 0.5; }
上述命令会将包含“ice”、“cream”和“sandwich”的文档权重设置为 0.5。您还可以根据子查询修改松弛度 ($slop) 和“顺序”要求 ($inorder)。
匹配单个字符距离内的任何项目。例如,“%redis%”不仅会匹配“redis”,还会匹配“jedis”和“predis”。
仅在满足条件时更新文档,例如:
FT.ADD idx myDoc 1.0 REPLACE PARTIAL IF "@timestamp < 12313134523" FIELDS title "new title"
当时间戳低于 12313134523 时,此代码会更新文档“myDoc”。它只会更新标题。
使用反斜杠作为转义符,以便控制字符被视为普通文本处理。此查询将在索引文档中查找“hello-world”和“world”
FT.SEARCH idx "hello-world world"
在拼写不同但完全等同的情况下,匹配可能会很棘手。使用 FT.SYNADD 和 FT.SYNUPDATE,您可以添加等同的术语,后续添加的文档将被匹配。例如:
FT.SYNADD idx hello hola hej bonjour
包含这些术语中任何一个的任何新文档都可以通过如下查询匹配到
FT.SEARCH idx hej
最后,1.2.0 版本是 Dvir 领导的最后一个 RediSearch 版本。我们很遗憾看到他离开,但祝愿他在新的组织开启新的冒险旅程(我们听说他正在构建的东西非常酷,并且与 RediSearch 非常不同)。不过请放心,RediSearch 正由 Redis 的一支完整团队开发,他们将继续创新并推动 RediSearch 向前发展。