RediSearch 0.91 版本添加了一个新的字段——标签字段。它类似于全文字段,但在索引中使用更简单的标记化和编码。这些字段中的值无法通过一般的无字段搜索访问,只能与特殊语法一起使用。
标签和全文字段之间的主要区别是:
- 我们不对标签索引执行词干提取。
- 标记化更简单:用户可以为多个标签确定一个分隔符(默认为逗号),我们只在标签末尾进行空格修剪。因此,标签可以包含空格、标点符号、重音符号等。我们执行的仅有的两个转换是小写(目前仅适用于拉丁语言)和空格修剪。
- 无法从一般全文搜索中找到标签。如果文档有一个名为“tags”的字段,其值为“foo”和“bar”,搜索 foo 或 bar 没有特殊的标签修饰符(见下文)将不会返回此文档。
- 索引更简单,更压缩:我们不存储频率,字段标志的偏移向量。该索引仅包含编码为增量的文档 ID。这意味着标签索引中的条目通常为一或两个字节长。这使它们非常高效和快速。
- 每个索引可以创建无限数量的标签字段,只要字段总数低于 1024。
可以使用以下语法将标记字段添加到 FT.ADD 中的架构中:
FT.CREATE ... SCHEMA ... {field_name} TAG [SEPARATOR {sep}]
SEPARATOR 默认为逗号 ( , ),可以是任何可打印的 ASCII 字符。例如:
FT.CREATE idx ON HASH PREFIX 1 test: SCHEMA tags TAG SEPARATOR ";"
如上所述,仅搜索没有任何修饰符的标签将不会检索包含它的文档。
查询中匹配标签的语法如下(在这种情况下,大括号是语法的一部分):
@<field_name>:{ <tag> | <tag> | ...}
例如,此查询查找带有标记 hello world 或 的 文档 foo bar :
FT.SEARCH idx "@tags:{ hello world | foo bar }"
标记子句可以组合成任何子句,用作否定表达式、可选表达式等。例如,给定以下索引:
FT.CREATE idx ON HASH PREFIX 1 test: SCHEMA title TEXT price NUMERIC tags TAG SEPARATOR ";"
您可以将 标题 字段上的全文搜索、 价格 上的数字范围 结合起来 ,并 像这样匹配 foo bar 或 hello world 标签:
FT.SEARCH idx "@title:hello @price:[0 100] @tags:{ foo bar | hello world }
请注意,在同一个子句中包含多个标签会创建包含任何包含标签的所有文档的联合。要创建包含 所有 给定标签的文档的交集 ,您应该多次重复标签过滤器。
例如,假设有一个旅行者索引,每个旅行者访问过的城市都有一个标签字段:
FT.CREATE myIndex ON HASH PREFIX 1 traveller: SCHEMA name TEXT cities TAG
HSET traveller:1 name "John Doe" cities "New York, Barcelona, San Francisco"
对于此索引,以下查询将返回 至少访问过 以下城市之一 的所有人 :
FT.SEARCH myIndex "@cities:{ New York | Los Angeles | Barcelona }"
但是下一个查询将返回所有访问过 所有三个城市的人 :
FT.SEARCH myIndex "@cities:{ New York } @cities:{Los Angeles} @cities:{ Barcelona }"
标签可以包含除字段分隔符之外的标点符号(默认情况下,逗号)。使用该 HSET 命令将值添加到 Redis 哈希时,您不需要转义标点符号 。
例如,给定以下索引:
FT.CREATE punctuation ON HASH PREFIX 1 test: SCHEMA tags TAG
您可以添加包含标点符号的标签,如下所示:
HSET test:1 tags "Andrew's Top 5,Justin's Top 5"
但是,当您查询包含标点符号的标签时,您必须使用反斜杠字符 ( \ )对该标点符号进行转义 。
注意 :在大多数语言中,您需要一个额外的反斜杠。在 redis-cli 中也是如此。
例如, Andrew's Top 5 在 redis-cli 中查询标签 如下所示:
FT.SEARCH punctuation "@tags:{ Andrew\\'s Top 5 }"
正如本文档中的示例所示,单个标签可以包含多个单词。我们建议您在查询时转义空格,尽管这样做不是必需的。
转义空格的方式与转义标点符号的方式相同——在空格前加一个反斜杠字符(或两个反斜杠,取决于编程语言和环境)。
因此,在 redis-cli 中查询时,您将像这样转义“成为或不成为”标签:
FT.SEARCH idx "@tags:{ to\\ be\\ or\\ not\\ to\\ be }"
您应该对空格进行转义,因为如果一个标签包含多个单词并且其中一些是 “to”或“be”等 停用词 ,那么包含这些单词但没有转义空格的查询将产生语法错误。
您可以在以下示例中看到它的样子:
127.0.0.1:6379> FT.SEARCH idx "@tags:{ to be or not to be }"
(error) Syntax error at offset 27 near be
注意: 停用词是很常见的词,以至于搜索引擎会忽略它们。 如果您想了解更多信息,我们有一个关于 RediSearch 中停用词 的专门页面 。
鉴于存在语法错误的可能性,我们建议您对标签查询中的所有空格进行转义。