FT.SEARCH

语法
FT.SEARCH index query 
  [NOCONTENT] 
  [VERBATIM] 
  [NOSTOPWORDS] 
  [WITHSCORES] 
  [WITHPAYLOADS] 
  [WITHSORTKEYS] 
  [FILTER numeric_field min max [ FILTER numeric_field min max ...]] 
  [GEOFILTER geo_field lon lat radius m | km | mi | ft [ GEOFILTER geo_field lon lat radius m | km | mi | ft ...]] 
  [INKEYS count key [key ...]] 
  [INFIELDS count field [field ...]] 
  [RETURN count identifier [AS property] [ identifier [AS property] ...]] 
  [SUMMARIZE [ FIELDS count field [field ...]] [FRAGS num] [LEN fragsize] [SEPARATOR separator]] 
  [HIGHLIGHT [ FIELDS count field [field ...]] [ TAGS open close]] 
  [SLOP slop] 
  [TIMEOUT timeout] 
  [INORDER] 
  [LANGUAGE language] 
  [EXPANDER expander] 
  [SCORER scorer] 
  [EXPLAINSCORE] 
  [PAYLOAD payload] 
  [SORTBY sortby [ ASC | DESC] [WITHCOUNT]] 
  [LIMIT offset num] 
  [PARAMS nargs name value [ name value ...]] 
  [DIALECT dialect]
可用版本
Redis Open Source / Search 1.0.0
时间复杂度
O(N)
ACL 分类
@read, @search,

使用文本查询搜索索引,返回文档或仅返回 ID。

注意
此命令仅返回用户具有读取访问权限的键。

示例

必选参数

index

是索引名称。您必须首先使用 FT.CREATE 创建索引。

query

是要搜索的文本查询。如果它不止一个单词,请用引号括起来。有关更多详细信息,请参阅 查询语法

可选参数

NOCONTENT

返回文档 ID 而不返回内容。如果 RediSearch 仅是外部文档集合的索引,此选项非常有用。

VERBATIM

不尝试使用词干提取进行查询扩展,而是按字面意义搜索查询词项。

NOSTOPWORDS

在全文搜索中忽略任何定义的停用词。

WITHSCORES

还返回每个文档的相对内部得分。这可用于合并来自多个实例的结果。

WITHPAYLOADS

检索可选的文档负载。请参阅 FT.CREATE。负载跟在文档 ID 之后,如果设置了 WITHSCORES,则跟在得分之后。

WITHSORTKEYS

如果请求,返回排序键的值,紧跟在 ID 和得分以及/或负载之后。这通常不需要,其存在是为了分布式搜索协调目的。此选项仅在与 SORTBY 结合使用时相关。

FILTER numeric_attribute min max

将结果限制为数字属性值在 minmax 范围内的文档,前提是 numeric_attributeFT.CREATE 中被定义为数字属性。minmax 遵循 ZRANGE 语法,可以是 -inf+inf,并使用 ( 表示独占范围。一个查询中支持对不同属性进行多个数字过滤。自 v2.10 起已弃用查询方言 2 解释了用于替换此参数的数字字段查询语法。

GEOFILTER {geo_attribute} {lon} {lat} {radius} m|km|mi|ft

将结果过滤到距离 lonlat 指定 radius 范围内的文档。半径以数字和单位给出。有关更多详细信息,请参阅 GEORADIUS自 v2.6 起已弃用查询方言 3 解释了用于替换此参数的地理空间字段查询语法。

INKEYS {num} {attribute} ...

将结果限制为列表中指定的给定键集。第一个参数必须是列表的长度且大于零。不存在的键将被忽略,除非所有键都不存在。

INFIELDS {num} {attribute} ...

将结果过滤到仅出现在文档特定属性(如 titleURL)中的文档。您必须包含 num,这是您要过滤的属性数量。例如,如果您请求 titleURL,则 num 为 2。

RETURN {num} {identifier} AS {property} ...

限制从文档返回的属性数量。num 是关键字后面的属性数量。如果 num 为 0,则其行为类似于 NOCONTENTidentifier 是属性名称(对于哈希和 JSON)或 JSONPath 表达式(对于 JSON)。property 是结果中使用的可选名称。如果未提供,则在结果中使用 identifier

SUMMARIZE ...

仅返回包含匹配文本的属性部分。有关更多信息,请参阅 高亮显示

HIGHLIGHT ...

格式化匹配文本的出现。有关更多信息,请参阅 高亮显示

SLOP {slop}

是查询词项之间允许出现的中间词项数量。假设您正在搜索短语 hello world。如果在 helloworld 之间出现了一些词项,则大于 0SLOP 允许这些文本属性匹配。默认情况下,没有 SLOP 约束。

INORDER

要求文档中的词项顺序与查询中的词项顺序相同,无论它们之间的偏移量如何。通常与 SLOP 结合使用。默认值为 false

LANGUAGE {language}

在搜索时使用提供的语言的词干提取器进行查询扩展。如果查询中文文档,请设置为 chinese 以正确分词查询词项。默认为英语。如果发送了不支持的语言,命令将返回错误。有关语言列表,请参阅 FT.CREATE。如果在索引创建时指定了 LANGUAGE,则无需在 FT.SEARCH 中再次指定。

EXPANDER {expander}

使用自定义查询扩展器代替词干提取器。请参阅 扩展

SCORER {scorer}

使用内置用户提供的 评分函数。

EXPLAINSCORE

返回关于得分如何计算的文本描述。使用此选项需要 WITHSCORES

PAYLOAD {payload}

添加任意二进制安全的负载,该负载暴露给自定义评分函数。请参阅 扩展

SORTBY {attribute} [ASC|DESC] [WITHCOUNT]

按此属性的值对结果排序。这适用于文本和数字属性。用于 SORTBY 的属性应在索引中声明为 SORTABLE,以便以非常低的延迟可用。请注意,这会增加内存开销。

排序优化: 在 DIALECT 4 中对不同场景的排序操作进行了性能优化

  • 跳过排序器 - 在没有任何排序时应用。查询在达到 LIMIT 请求的结果数量后即可返回。
  • 部分范围 - 在数字字段上存在 SORTBY 子句,且没有过滤或按相同数字字段过滤时应用,查询会在足够大的范围内迭代,以满足 LIMIT 请求的结果数量。
  • 混合 - 在数字字段上存在 SORTBY 子句和另一个非数字过滤器时应用。部分结果将被过滤,初始范围可能不够大。然后迭代器会回退到后续范围,并进行额外的迭代以收集 LIMIT 请求的结果数量。
  • 无优化 - 如果按得分或非数字字段排序,则只能检索所有结果并比较其值。

计数行为: 可选的WITHCOUNT参数在进行排序时返回准确的查询结果计数。此操作处理所有结果以获取准确计数,其性能低于优化选项(DIALECT 4 上的默认行为)

LIMIT first num

限制结果的偏移量和数量。请注意,偏移量是从零开始的。默认是 0 10,表示从第一个结果开始返回 10 个项。您可以使用 LIMIT 0 0 计算结果集中的文档数量而不实际返回它们。

LIMIT 行为: 如果您在没有排序的情况下使用 LIMIT 选项,返回的结果是非确定性的,这意味着后续查询可能会返回重复或缺失的值。添加带有唯一字段的 SORTBY,或使用带有 WITHCURSOR 选项的 FT.AGGREGATE 以确保确定的结果集分页。

TIMEOUT {milliseconds}

覆盖模块的超时参数。

PARAMS {nargs} {name} {value}

定义一个或多个值参数。每个参数都有一个名称和一个值。

您可以在 query 中通过后跟参数名的 $ 来引用参数,例如 $user。搜索查询中对此类参数名的每个引用都会被相应的参数值替换。例如,使用参数定义 PARAMS 4 lon 29.69465 lat 34.95126,表达式 @loc:[$lon $lat 10 km] 会被评估为 @loc:[29.69465 34.95126 10 km]。您不能在不允许具体值的查询字符串中引用参数,例如在字段名称中,如 @loc。要使用 PARAMS,请将 DIALECT 设置为 2 或大于 2(这需要 RediSearch v2.4 或更高版本)。

DIALECT {dialect_version}

选择执行查询所用的方言版本。如果未指定,查询将使用模块初始加载时或通过 FT.CONFIG SET 命令设置的默认方言版本。有关更多信息,请参阅 查询方言

返回值

FT.SEARCH 返回一个数组回复,其中第一个元素是总结果数的整数回复,然后是文档 ID 的数组回复对,以及属性/值对的数组回复。

备注
  • 如果提供了 NOCONTENT,则返回一个数组,其中第一个元素是总结果数,其余成员是文档 ID。
  • 如果在查询运行时相关键过期,尝试加载键的值将返回 null 数组。但是,该键仍会计入总结果数中。

返回多个值

当索引定义为 ON JSON 时,如果 JSONPath 匹配多个值或匹配一个数组,单个属性或单个 JSONPath 的回复可能返回多个值。

在 RediSearch v2.6 之前,仅返回第一个匹配的值。从 RediSearch v2.6 开始,所有值都将返回,并包含在一个顶层数组中。

为了保持向后兼容性,RediSearch v2.6 的默认行为是仅返回第一个值。

要返回所有值,请使用 DIALECT 3(或更高版本,如果可用)。

可以在 FT.SEARCH 命令中将 DIALECT 指定为参数。如果未指定,则使用 DEFAULT_DIALECT,该参数可以使用 FT.CONFIG SET 或在加载 redisearch 模块时作为参数传递来设置。

例如,使用以下文档和索引

127.0.0.1:6379> JSON.SET doc:1 $ '[{"arr": [1, 2, 3]}, {"val": "hello"}, {"val": "world"}]'
OK
127.0.0.1:6379> FT.CREATE idx ON JSON PREFIX 1 doc: SCHEMA $..arr AS arr NUMERIC $..val AS val TEXT
OK

注意使用和不使用 DIALECT 3 时的不同回复

127.0.0.1:6379> FT.SEARCH idx * RETURN 2 arr val
1) (integer) 1
2) "doc:1"
3) 1) "arr"
   2) "[1,2,3]"
   3) "val"
   4) "hello"

127.0.0.1:6379> FT.SEARCH idx * RETURN 2 arr val DIALECT 3
1) (integer) 1
2) "doc:1"
3) 1) "arr"
   2) "[[1,2,3]]"
   3) "val"
   4) "[\"hello\",\"world\"]"

复杂度

FT.SEARCH 对于单词查询的复杂度为 O(n)。n 是结果集中的结果数量。查找包含特定词项的所有文档的复杂度为 O(1),但是,需要扫描所有这些文档以从 redis hash 中加载文档数据并返回它们。

更复杂查询的时间复杂度各不相同,但通常与词项数量、它们之间的交点数量以及结果集中的结果数量成比例。

示例

在每个文本属性中搜索词项

在包含书籍数据的索引的每个 TEXT 属性中搜索词项“wizard”。

127.0.0.1:6379> FT.SEARCH books-idx "wizard"
在 title 属性中搜索词项

title 属性中搜索词项 dogs

127.0.0.1:6379> FT.SEARCH books-idx "@title:dogs"
搜索特定年份的书籍

搜索在 2020 年或 2021 年出版的书籍。

127.0.0.1:6379> FT.SEARCH books-idx "@published_at:[2020 2021]"
按经/纬度距离搜索餐厅

搜索距离经度 -122.41、纬度 37.77(旧金山)5 公里范围内的中餐厅。

127.0.0.1:6379> FT.SEARCH restaurants-idx "chinese @location:[-122.41 37.77 5 km]"
按词项搜索书籍但提升特定词项

title 属性中搜索词项 dogscats,但给予匹配 dogs 的结果更高的相关性得分(也称为提升)。

127.0.0.1:6379> FT.SEARCH books-idx "(@title:dogs | @title:cats) | (@title:dogs) => { $weight: 5.0; }"
按词项搜索书籍并解释得分

在索引的任何 TEXT 属性中搜索包含 dogs 的书籍,并请求解释每个结果的得分计算过程。

127.0.0.1:6379> FT.SEARCH books-idx "dogs" WITHSCORES EXPLAINSCORE
按词项和 TAG 搜索书籍

搜索标题中包含 space 且 TAG 属性 categories 中包含 science 的书籍。

127.0.0.1:6379> FT.SEARCH books-idx "@title:space @categories:{science}"
按词项搜索书籍但限制数量

在任何 TEXT 属性中搜索包含 Python 的书籍,返回从整个结果集中的第 11 个结果开始的 10 个结果(偏移量参数是基于零的),并且仅返回每个结果的 title 属性。

127.0.0.1:6379> FT.SEARCH books-idx "python" LIMIT 10 10 RETURN 1 title
按词项和价格搜索书籍

在任何 TEXT 属性中搜索包含 Python 的书籍,返回存储在原始 JSON 文档中的价格。

127.0.0.1:6379> FT.SEARCH books-idx "python" RETURN 3 $.book.price AS price
按标题和距离搜索书籍

搜索与 Planet Earth 标题语义相似的书籍。返回按距离排序的前 10 个结果。

127.0.0.1:6379> FT.SEARCH books-idx "*=>[KNN 10 @title_embedding $query_vec AS title_score]" PARAMS 2 query_vec <"Planet Earth" embedding BLOB> SORTBY title_score DIALECT 2
使用 SLOP 搜索短语

搜索短语 hello world。首先,创建一个索引。

127.0.0.1:6379> FT.CREATE memes SCHEMA phrase TEXT
OK

添加短语 hello world 的变体。

127.0.0.1:6379> HSET s1 phrase "hello world"
(integer) 1
127.0.0.1:6379> HSET s2 phrase "hello simple world"
(integer) 1
127.0.0.1:6379> HSET s3 phrase "hello somewhat less simple world"
(integer) 1
127.0.0.1:6379> HSET s4 phrase "hello complicated yet encouraging problem solving world"
(integer) 1
127.0.0.1:6379> HSET s5 phrase "hello complicated yet amazingly encouraging problem solving world"
(integer) 1

然后,搜索短语 hello world。结果返回所有包含该短语的文档。

127.0.0.1:6379> FT.SEARCH memes '@phrase:(hello world)' NOCONTENT 
1) (integer) 5
2) "s1"
3) "s2"
4) "s3"
5) "s4"
6) "s5"

现在,返回所有在 helloworld 之间有一个或更少词语的文档。

127.0.0.1:6379> FT.SEARCH memes '@phrase:(hello world)' NOCONTENT SLOP 1
1) (integer) 2
2) "s1"
3) "s2"

现在,返回所有在 helloworld 之间有三个或更少词语的文档。

127.0.0.1:6379> FT.SEARCH memes '@phrase:(hello world)' NOCONTENT SLOP 3
1) (integer) 3
2) "s1"
3) "s2"
4) "s3"

s5 需要更高的 SLOP 才能匹配,准确地说,是 SLOP 6 或更高。看看将 SLOP 设置为 5 时会发生什么。

127.0.0.1:6379> FT.SEARCH memes '@phrase:(hello world)' NOCONTENT SLOP 5
1) (integer) 4
2) "s1"
3) "s2"
4) "s3"
5) "s4"

如果您添加额外的词项(和词干提取),您将得到这些结果。

127.0.0.1:6379> FT.SEARCH memes '@phrase:(hello amazing world)' NOCONTENT 
1) (integer) 1
2) "s5"
127.0.0.1:6379> FT.SEARCH memes '@phrase:(hello encouraged world)' NOCONTENT SLOP 5
1) (integer) 2
2) "s4"
3) "s5"
127.0.0.1:6379> FT.SEARCH memes '@phrase:(hello encouraged world)' NOCONTENT SLOP 4
1) (integer) 1
2) "s4"

如果您交换词项,仍然可以检索到正确的短语。

127.0.0.1:6379> FT.SEARCH memes '@phrase:(amazing hello world)' NOCONTENT
1) (integer) 1
2) "s5"

但是,如果您使用 INORDER,您将得到零结果。

127.0.0.1:6379> FT.SEARCH memes '@phrase:(amazing hello world)' NOCONTENT INORDER
1) (integer) 0

同样,如果您使用设置为 true 的查询属性 $inorder,则不会检索到 s5

127.0.0.1:6379> FT.SEARCH memes '@phrase:(amazing hello world)=>{$inorder: true;}' NOCONTENT
1) (integer) 0

总而言之,INORDER 参数或 $inorder 查询属性要求查询词项匹配顺序相似的词项。

使用 WITHIN、CONTAINS、INTERSECTS 和 DISJOINT 运算符进行多边形搜索

查询符合以下条件的多边形

  • 包含给定的地理形状
  • 在给定的地理形状内
  • 与给定的地理形状相交
  • 与给定的形状不相交(没有共同点)

INTERSECTSDISJOINT 在 v2.10 中引入。

首先,使用 GEOSHAPE 类型创建一个索引,并使用 FLAT 坐标系

127.0.0.1:6379> FT.CREATE idx SCHEMA geom GEOSHAPE FLAT
OK

使用 HSET 添加一些几何形状

127.0.0.1:6379> HSET small geom 'POLYGON((1 1, 1 100, 100 100, 100 1, 1 1))'
(integer) 1
127.0.0.1:6379> HSET large geom 'POLYGON((1 1, 1 200, 200 200, 200 1, 1 1))'
(integer) 1

使用 WITHIN 运算符进行查询

127.0.0.1:6379> FT.SEARCH idx '@geom:[WITHIN $poly]' PARAMS 2 poly 'POLYGON((0 0, 0 150, 150 150, 150 0, 0 0))' DIALECT 3

1) (integer) 1
2) "small"
3) 1) "geom"
   2) "POLYGON((1 1, 1 100, 100 100, 100 1, 1 1))"

使用 CONTAINS 运算符进行查询

127.0.0.1:6379> FT.SEARCH idx '@geom:[CONTAINS $poly]' PARAMS 2 poly 'POLYGON((2 2, 2 50, 50 50, 50 2, 2 2))' DIALECT 3

1) (integer) 2
2) "small"
3) 1) "geom"
   2) "POLYGON((1 1, 1 100, 100 100, 100 1, 1 1))"
4) "large"
5) 1) "geom"
   2) "POLYGON((1 1, 1 200, 200 200, 200 1, 1 1))"

另请参阅

FT.CREATE | FT.AGGREGATE


历史

  • 从 Redis 2.0.0 版本开始:WITHPAYLOADS 和 PAYLOAD 参数已弃用
  • 从 Redis 2.6 版本开始:GEOFILTER 参数已弃用
  • 从 Redis 2.10 版本开始:FILTER 参数已弃用
评价此页
返回顶部 ↑
© . This site is unofficial and not affiliated with Redis, Inc.