查询方言
了解如何使用查询方言
Redis Stack 目前支持四种查询方言,用于与 FT.SEARCH
、FT.AGGREGATE
和其他搜索和查询命令一起使用。方言允许以不破坏现有应用程序 API 的方式逐步增强查询 API,引入支持新用例的创新行为和新功能。
方言 1
方言版本 1 是从搜索和查询的第一个版本发布开始到版本 2.4 引入方言版本 2 之前的默认查询语法方言。该方言也是默认方言。有关更改默认方言的信息,请参见下文。
方言 2
方言版本 2 在 2.4 版本中引入,用于解决 Redis Stack 以前版本中发现的查询解析器不一致问题。方言版本 1 仍然是默认方言。要使用方言版本 2,请在查询命令后面追加 DIALECT 2
。向量搜索支持也在 2.4 版本中引入,并且需要 DIALECT 2
。有关更多详细信息,请参见 这里。FT.SEARCH ... DIALECT 2
已确定,在某些情况下,某些查询解析规则的行为与最初的预期不符。特别是,包含以下运算符的某些查询可能会返回意外的结果。
- AND,暗示交集的多词短语
"..."
(精确)、~
(可选)、-
(否定)和%
(模糊)- OR,由
|
(管道)字符分隔的暗示并集的词语 - 通配符字符
如果使用方言 1 的现有查询属于以下任何类别,则使用方言 2 时其行为可能会有所不同。
-
您的查询包含字段修饰符,后跟多个词语。考虑以下示例查询:
@name:James Brown
这里,字段修饰符
@name
后面是两个词语,James
和Brown
。在
DIALECT 1
中,此查询将被解释为在@name
字段中查找James Brown
。在DIALECT 2
中,此查询将被解释为在@name
字段中查找James
,并在任何文本字段中查找Brown
。换句话说,它将被解释为(@name:James) Brown
。在DIALECT 2
中,您可以通过将查询更新为@name:(James Brown)
来实现方言 1 的行为。 -
您的查询使用
"..."
、~
、-
和/或%
。考虑一个带有否定的简单查询:-hello world
在
DIALECT 1
中,此查询被解释为查找任何字段中不包含hello
且不包含world
的值;等效于-(hello world)
或-hello -world
。在DIALECT 2
中,此查询被解释为-hello
和world
(仅否定hello
)。在DIALECT 2
中,您可以通过将查询更新为-(hello world)
来实现方言 1 的行为。 -
您的查询使用
|
。考虑以下简单查询:hello world | "goodbye" moon
在
DIALECT 1
中,此查询被解释为搜索(hello world | "goodbye") moon
。在DIALECT 2
中,此查询被解释为搜索hello world
或"goodbye" moon
。 -
您的查询使用通配符模式。考虑以下简单查询:
"w'foo*bar?'"
如上所示,您必须使用双引号来包含
w
模式。
在 DIALECT 2
中,即使有停用词,您也可以在标签查询中使用未转义的空格。
DIALECT 2
。DIALECT 2
功能在 2.10 版本中得到了增强。它引入了对 NUMERIC
字段的新比较运算符的支持
-
==
(等于)。FT.SEARCH idx "@numeric==3456" DIALECT 2
和
FT.SEARCH idx "@numeric:[3456]" DIALECT 2
-
!=
(不等于)。FT.SEARCH idx "@numeric!=3456" DIALECT 2
-
>
(大于)。FT.SEARCH idx "@numeric>3456" DIALECT 2
-
>=
(大于或等于)。FT.SEARCH idx "@numeric>=3456" DIALECT 2
-
<
(小于)。FT.SEARCH idx "@numeric<3456" DIALECT 2
-
<=
(小于或等于)。FT.SEARCH idx "@numeric<=3456" DIALECT 2
方言版本 2 的增强功能还引入了简化的逻辑运算语法
-
|
(或)。FT.SEARCH idx "@tag:{3d3586fe-0416-4572-8ce1 | 3d3586fe-0416-6758-4ri8}" DIALECT 2
等效于
FT.SEARCH idx "(@tag:{3d3586fe-0416-4572-8ce1} | @tag{3d3586fe-0416-6758-4ri8})" DIALECT 2
-
<space>
(和)。FT.SEARCH idx "(@tag:{3d3586fe-0416-4572-8ce1} @tag{3d3586fe-0416-6758-4ri8})" DIALECT 2
-
-
(否定)。FT.SEARCH idx "(@tag:{3d3586fe-0416-4572-8ce1} -@tag{3d3586fe-0416-6758-4ri8})" DIALECT 2
-
~
(可选/接近)。FT.SEARCH idx "(@tag:{3d3586fe-0416-4572-8ce1} ~@tag{3d3586fe-0416-6758-4ri8})" DIALECT 2
方言版本 3
方言版本 3 在 2.6 版本中引入。此版本引入了对任何属性类型(TEXT、TAG、NUMERIC、GEO 和 VECTOR)的属性的多值索引和查询的支持,这些属性由指向数组或多个标量值的 JSONPath 定义。此方言还引入了对 GEOSHAPE 查询的支持。
方言版本 2 和版本 3 之间的主要区别在于,对于多值属性,JSON 而不是标量会被返回。除了在 FT.SEARCH
命令的末尾指定 DIALECT 3
之外,没有其他语法更改。方言版本 1 仍然是默认方言。要使用方言版本 3,请在查询命令后面追加 DIALECT 3
。
FT.SEARCH ... DIALECT 3
示例
示例 JSON
{
"id": 123,
"underlyings": [
{
"currency": "USD",
"spot": 99,
"underlier": "AAPL UW"
},
{
"currency": "USD",
"spot": 100,
"underlier": "NFLX UW"
}
]
}
创建索引
FT.CREATE js_idx ON JSON PREFIX 1 js: SCHEMA $.underlyings[*].underlier AS und TAG
现在搜索,带和不带 DIALECT 3
。
-
使用方言 1(默认)
ft.search js_idx * return 1 und 1) (integer) 1 2) "js:1" 3) 1) "und" 2) "AAPL UW"
仅返回预期两个元素中的第一个元素。
-
使用方言 3
ft.search js_idx * return 1 und DIALECT 3 1) (integer) 1 2) "js:1" 3) 1) "und" 2) "[\"AAPL UW\",\"NFLX UW\"]"
两个元素都将被返回。
POINT
或 POLYGON
)地理空间查询需要 DIALECT 3
。方言版本 4
方言版本 4 在 2.8 版本中引入。它引入了对 FT.SEARCH
和 FT.AGGREGATE
上的排序操作的性能优化。除了在 FT.SEARCH
命令的末尾指定 DIALECT 4
之外,没有其他语法更改。方言版本 1 仍然是默认方言。要使用方言版本 4,请在查询命令后面追加 DIALECT 4
。
FT.SEARCH ... DIALECT 4
方言版本 4 将在四种不同的情况下提高性能
- 跳过排序器 - 当没有排序要执行时应用。查询可以在达到请求结果的
LIMIT
时返回。 - 部分范围 - 当对数字字段进行
SORTBY
时应用,无论是没有过滤器还是通过相同的数字字段进行过滤。此类查询将迭代足够大的范围以满足请求结果的LIMIT
。 - 混合 - 当除了另一个非数字过滤器之外,对数字字段进行
SORTBY
时应用。可能有些结果会被过滤掉,导致范围太小而无法满足任何指定的LIMIT
。在这种情况下,迭代器将被重绕,并进行额外的迭代以收集最多请求LIMIT
的结果。 - 无优化 - 如果按分数或非数字字段排序,则别无选择,只能检索所有结果并将其值与搜索参数进行比较。
使用 FT.EXPLAINCLI
来比较方言
FT.EXPLAINCLI
命令是一个强大的工具,可以让你了解查询的内部工作原理。它就像一个路线图,详细说明了查询从开始到结束的旅程。
当您运行 FT.EXPLAINCLI
时,它将返回一个数组,代表复杂查询的执行计划。该计划是 Redis 如何解释您的查询以及如何计划获取结果的分步指南。它是在幕后查看该过程,让您深入了解搜索引擎的工作原理。
FT.EXPLAINCLI
接受一个 DIALECT
参数,允许您使用不同的方言版本执行查询,从而使您能够比较生成的查询计划。
要使用 FT.EXPLAINCLI
,您需要提供索引和查询谓词。索引是您使用 FT.CREATE
创建的索引的名称,查询谓词与您将其发送到 FT.SEARCH
或 FT.AGGREGATE
时相同。
以下是如何使用 FT.EXPLAINCLI
来理解方言版本 1 和 2 之间差异的示例。
对标记 hello
和 world
之间交集的否定
1) NOT {
2) INTERSECT {
3) hello
4) world
5) }
6) }
7)
对标记 hello
的否定的交集与标记 world
一起
FT.EXPLAINCLI idx:dialects "-hello world" DIALECT 2
1) INTERSECT {
2) NOT {
3) hello
4) }
5) UNION {
6) world
7) +world(expanded)
8) }
9) }
10)
与 DIALECT 1
相同的结果
FT.EXPLAINCLI idx:dialects "-(hello world)" DIALECT 2
1) NOT {
2) INTERSECT {
3) hello
4) world
5) }
6) }
7)
FT.EXPLAIN
不会执行查询。它只解释计划。它是了解查询引擎如何解释您的查询的一种方法,这在您尝试优化搜索时非常宝贵。更改默认方言
默认方言是 DIALECT 1
。如果您想更改它,可以使用加载 RediSearch 模块时的 DEFAULT_DIALECT
参数进行更改
$ redis-server --loadmodule ./redisearch.so DEFAULT_DIALECT 2
您还可以使用 FT.CONFIG
命令在正在运行的服务器上更改查询方言
FT.CONFIG SET DEFAULT_DIALECT 2