查询方言

学习如何使用查询方言

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

DIALECT 1

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

DIALECT 2

方言版本2在2.4版本中引入,以解决Redis Stack早期版本中查询解析器的不一致性问题。方言版本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

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

  • (和).

    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. 部分范围 - 当在数字字段上有SORTBY时应用,无论是否有过滤器或使用相同数字字段的过滤器。此类查询将在足够大的范围内迭代,以满足请求结果的LIMIT
  3. 混合 - 当在数字字段上有SORTBY并且还有另一个非数字过滤器时应用。可能会出现一些结果被过滤掉,导致范围太小无法满足任何指定的LIMIT。在这种情况下,迭代器会重新启动,并进行额外的迭代以收集达到请求的LIMIT的结果。
  4. 无优化 - 如果按分数或非数字字段排序,除了检索所有结果并将其值与搜索参数进行比较外,没有其他选择。

使用 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
RATE THIS PAGE
Back to top ↑