查询方言

了解如何使用查询方言

Redis Stack 目前支持四种查询方言,用于FT.SEARCH,FT.AGGREGATE和其他 Redis 查询引擎命令。 Dialects 提供增量增强查询 API,引入创新行为和新功能,以支持新用例,而不会破坏现有应用程序的 API。

DIALECT 1

Dialect 版本 1 是 search and query 的第一个版本到版本 2.4 引入 dialect 版本 2 的默认查询语法方言。 此方言也是默认方言。有关更改默认方言的信息,请参阅下文。

DIALECT 2

Dialect 版本 2 是在 2.4 版本中引入的,用于解决以前版本的 Redis Stack 中发现的查询解析器不一致问题。Dialect 版本 1 仍然是默认方言。要使用 dialect 版本 2,请将DIALECT 2添加到您的 query 命令中。 2.4 版本中还引入了对向量搜索的支持,并且需要DIALECT 2.有关更多详细信息,请参阅此处FT.SEARCH ... DIALECT 2

已确定,在某些情况下,某些查询解析规则的行为与最初的预期不同。 特别是,某些包含以下运算符的查询可能会返回意外结果。

  1. AND,暗示交集的多词短语
  2. "..."(精确)、(可选)、(否定)和(模糊)~-%
  3. 或者,用|(竖线) 字符,表示联合
  4. 通配符

如果使用方言 1 的现有查询属于以下任何类别,则使用方言 2 时的行为可能会有所不同:

  1. 您的查询有一个 field 修饰符,后跟多个单词。请考虑示例查询:

    @name:James Brown

    此处,字段修饰符@name后面跟着两个字,JamesBrown.

    DIALECT 1,此查询将被解释为 findJames Brown@name田。 在DIALECT 2,此查询将被解释为 findJames@namefield 和Brown在任何文本字段中。换句话说,它将被解释为(@name:James) Brown. 在DIALECT 2,您可以通过将查询更新为@name:(James Brown).

  2. 您的查询使用"..."、、 、 和/或 .考虑一个带有否定的简单查询:~-%

    -hello world

    DIALECT 1,则此查询将解释为在不包含hello且不包含world;相当于-(hello world)-hello -world. 在DIALECT 2,则此查询将解释为-helloworld(仅限hello是否定的)。 在DIALECT 2,您可以通过将查询更新为-(hello world).

  3. 您使用的查询|.考虑简单的查询:

    hello world | "goodbye" moon

    DIALECT 1,则此查询将解释为搜索(hello world | "goodbye") moon. 在DIALECT 2,则此查询将解释为搜索hello world "goodbye" moon.

  4. 您的查询使用通配符模式。考虑简单的查询:

    "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

Dialect 版本 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

DIALECT 3

Dialect 版本 3 是在 2.6 版本中引入的。此版本引入了对多值索引和属性查询的支持,这些属性类型(TEXT、TAGNUMERIC、GEOVECTOR)由 JSONPath 定义,可导致数组或多个标量值。此方言中还引入了对 GEOSHAPE 查询的支持。

方言版本 2 和版本 3 之间的主要区别在于,对于多值属性,返回的是 JSON,而不是标量。除了指定DIALECT 3FT.SEARCH命令,则没有其他语法更改。Dialect 版本 1 仍然是默认方言。要使用 dialect 版本 3,请将DIALECT 3添加到您的 query 命令中。

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.

  • 使用 dialect 1(默认):

    ft.search js_idx * return 1 und
      1) (integer) 1
      2) "js:1"
      3) 1) "und"
         2) "AAPL UW"
    

    仅返回预期两个元素中的第一个元素。

  • 使用 dialect 3:

    ft.search js_idx * return 1 und DIALECT 3
        1) (integer) 1
        2) "js:1"
        3) 1) "und"
           2) "[\"AAPL UW\",\"NFLX UW\"]"
    

    返回两个元素。

注意:
DIALECT 3 对于基于形状 (POINTPOLYGON) 地理空间查询。

DIALECT 4

Dialect 版本 4 是在 2.8 版本中引入的。它引入了对FT.SEARCHFT.AGGREGATE.除了指定DIALECT 4FT.SEARCH命令,则没有其他语法更改。Dialect 版本 1 仍然是默认方言。要使用 dialect 版本 4,请将DIALECT 4添加到您的 query 命令中。

FT.SEARCH ... DIALECT 4

Dialect 版本 4 将在四种不同情况下提高性能:

  1. Skip sorter - 在没有要完成的排序时应用。查询到达LIMIT请求的结果。
  2. 部分范围 - 当存在SORTBY在数值字段上,要么没有过滤器,要么有按同一数值字段的过滤器。此类查询将迭代足够大的范围以满足LIMIT请求的结果。
  3. Hybrid - 在存在SORTBY在数值字段上,以及另一个非数值过滤器。可能会出现某些结果将被过滤的情况,留下的范围太小而无法满足任何指定的LIMIT.在这种情况下,迭代器将重新缠绕,并发生其他迭代以收集结果,直到收到请求的结果LIMIT.
  4. 无优化 - 如果存在按分数或非数字字段排序,则除了检索所有结果并将其值与搜索参数进行比较外,别无选择。

FT.EXPLAINCLI比较方言

FT.EXPLAINCLICommand 是一个强大的工具,它提供了一个了解查询内部工作原理的窗口。它就像一个路线图,详细说明了您的查询从头到尾的旅程。

当您运行FT.EXPLAINCLI,则返回一个数组,该数组表示复杂查询的执行计划。此计划是 Redis 如何解释您的查询以及它计划如何获取结果的分步指南。这是对该过程的幕后观察,让您深入了解搜索引擎的工作原理。

FT.EXPLAINCLI接受DIALECT参数,允许您使用不同的方言版本执行查询,从而允许您比较生成的查询计划。

要使用FT.EXPLAINCLI,您需要提供索引和查询谓词。索引是您使用的索引的名称FT.CREATE,并且查询谓词与将其发送到FT.SEARCHFT.AGGREGATE.

下面是一个如何使用FT.EXPLAINCLI了解 Dialect 版本 1 和 2 中的差异。

标记之间交集的否定helloworld:

1) NOT {
2)   INTERSECT {
3)     hello
4)     world
5)   }
6) }
7)

标记否定的交集hello连同 Tokenworld:

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.如果你想改变它,你可以使用DEFAULT_DIALECT参数:

$ redis-server --loadmodule ./redisearch.so DEFAULT_DIALECT 2

您还可以使用FT.CONFIG命令:

FT.CONFIG SET DEFAULT_DIALECT 2