查询方言

了解如何使用查询方言

Redis 开源版目前支持四种查询方言,可用于 FT.SEARCHFT.AGGREGATE 及其他 Redis 查询引擎命令。方言旨在逐步增强查询 API,引入创新行为和新功能,以支持新的用例,且不破坏现有应用的 API。

注意
在 Redis 开源版 Redis 8 中,方言 1、3 和 4 已弃用。但是,DIALECT 1 仍是默认方言。

DIALECT 1 (已弃用)

方言版本 1 是从搜索和查询首次发布到版本 2.4 引入方言版本 2 之前的默认查询语法方言。此方言也是默认方言。有关更改默认方言的信息,请参见下文。

DIALECT 2

方言版本 2 在 2.4 版本中引入,旨在解决 Redis 之前版本中发现的查询解析器不一致问题。方言版本 1 仍是默认方言。要使用方言版本 2,请在查询命令末尾加上 DIALECT 2。向量搜索支持也在 2.4 版本中引入,需要使用 DIALECT 2。更多详细信息,请参阅此处FT.SEARCH ... DIALECT 2

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

  1. AND,表示交集的多词短语
  2. "..." (精确匹配), ~ (可选), - (否定), 和 % (模糊匹配)
  3. OR,由 | (管道) 字符分隔的单词,表示并集
  4. 通配符

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

  1. 您的查询中有一个字段修饰符后跟多个单词。考虑以下示例查询

    @name:James Brown

    此处,字段修饰符 @name 后跟两个单词:JamesBrown

    DIALECT 1 中,此查询将被解释为在 @name 字段中查找 James Brown。在 DIALECT 2 中,此查询将被解释为在 @name 字段中查找 James,并在任何文本字段中查找 Brown。换句话说,它将被解释为 (@name:James) Brown。在 DIALECT 2 中,您可以通过将查询更新为 @name:(James Brown) 来实现方言 1 的行为。

  2. 您的查询使用了 "..."~- 和/或 %。考虑一个简单的否定查询

    -hello world

    DIALECT 1 中,此查询被解释为在不包含 hello 和不包含 world 的任何字段中查找值;相当于 -(hello world)-hello -world。在 DIALECT 2 中,此查询被解释为 -helloworld(只有 hello 被否定)。在 DIALECT 2 中,您可以通过将查询更新为 -(hello world) 来实现方言 1 的行为。

  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

方言版本 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 (已弃用)

方言版本 3 在 2.6 版本中引入。此版本引入了对任何属性类型(TEXTTAGNUMERICGEOVECTOR)的多值索引和查询支持,这些属性由指向数组或多个标量值的 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\"]"
    

    两个元素都返回了。

注意
基于形状(POINTPOLYGON)的地理空间查询需要使用 DIALECT 3。

DIALECT 4 (已弃用)

方言版本 4 在 2.8 版本中引入。它引入了对 FT.SEARCHFT.AGGREGATE 排序操作的性能优化。除了在 FT.SEARCH 命令末尾指定 DIALECT 4 外,没有其他语法更改。方言版本 1 仍是默认方言。要使用方言版本 4,请在查询命令末尾加上 DIALECT 4

FT.SEARCH ... DIALECT 4

方言版本 4 将在四种不同场景下提升性能

  1. 跳过排序器 - 在无需排序时应用。查询在达到所需结果的 LIMIT 后即可返回。
  2. 部分范围 - 在对 numeric 字段进行 SORTBY 排序,且无过滤器或仅对同一 numeric 字段进行过滤时应用。此类查询将在足以满足所需结果的 LIMIT 的范围内进行迭代。
  3. 混合 - 在对 numeric 字段进行 SORTBY 排序且同时存在其他非 numeric 过滤器时应用。在这种情况下,部分结果可能会被过滤掉,导致满足指定 LIMIT 的范围太小。此时,迭代器会回卷并进行额外的迭代,以收集达到所需 LIMIT 的结果。
  4. 无优化 - 如果按评分或非 numeric 字段排序,则只能检索所有结果并将其值与搜索参数进行比较。

使用 FT.EXPLAINCLI 比较方言

FT.EXPLAINCLI 命令是一个功能强大的工具,它能帮助您深入了解查询的内部工作原理。它就像一张路线图,详细描述了您的查询从开始到结束的整个过程。

运行 FT.EXPLAINCLI 时,它会返回一个数组,表示复杂查询的执行计划。此计划是一份分步指南,说明 Redis 如何解释您的查询以及如何计划获取结果。这是对幕后过程的查看,可让您了解搜索引擎的工作方式。

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

要使用 FT.EXPLAINCLI,您需要提供索引和查询谓词。索引是您使用 FT.CREATE 创建的索引名称,查询谓词与发送给 FT.SEARCHFT.AGGREGATE 的谓词相同。

以下是使用 FT.EXPLAINCLI 了解方言版本 1 和 2 之间差异的示例。

否定词元 helloworld 之间的交集

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
评价本页
返回顶部 ↑