FT.SEARCH
在索引中执行文本查询,返回匹配的文档或文档 ID。
语法
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 [GEOFILTER geo field lon lat radius ...]] [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]] [LIMIT offset num] [PARAMS nargs name value [name value ...]] [DIALECT dialect]
引入版本:1.0.0
复杂度摘要:O(N)
使用文本查询搜索索引,返回文档或仅返回 ID。
[!NOTE] 此命令将仅返回用户具有读取访问权限的键。
必需参数
index
是索引名称。您必须首先使用 FT.CREATE 创建索引。
query
是文本查询来搜索。如果它超过一个单词,请将其放在引号中。请参阅 查询语法 了解更多详细信息。
可选参数
NOCONTENT
返回文档ID而不是内容。如果 RediSearch 只是外部文档集合上的索引,这非常有用。
VERBATIM
不尝试使用词干进行查询扩展,而是逐字搜索查询词。
NOSTOPWORDS (deprecated)
忽略全文搜索中任何定义的停用词。注意:从 Redis 8.0 开始,此选项已弃用。
WITHSCORES
还返回每个文档的相对内部分数。这可用于合并多个实例的结果。
WITHPAYLOADS
检索可选的文档有效负载。请参阅 FT.CREATE。有效负载跟随文档 ID,如果设置了 WITHSCORES,则跟随分数。
WITHSORTKEYS
如果需要,则在 id 和分数和/或有效负载之后返回排序键的值。这通常是不需要的,其存在是为了分布式搜索协调目的。该选项仅在与 SORTBY 结合使用时才相关。
FILTER numeric_attribute min max
如果 numeric_attribute 被定义为 FT.CREATE 中的数字属性,则将结果限制为具有介于 min 和 max 之间的数值的结果。 min 和 max 遵循 ZRANGE 语法,可以是 -inf、+inf,并使用 ( 表示独占范围。一个查询中支持针对不同属性的多个数字过滤器。 自 v2.10 起已弃用:查询方言2 解释了替换此参数的数字字段的查询语法。
GEOFILTER {geo_attribute} {lon} {lat} {radius} m|km|mi|ft
将结果从 lon 和 lat 过滤到给定的 radius。半径以数字和单位的形式给出。有关更多详细信息,请参阅 GEORADIUS。 自 v2.6 起已弃用:查询方言3 解释了替换此参数的地理空间字段的查询语法。
INKEYS {num} {attribute} ...
将结果限制为列表中指定的一组给定键。第一个参数必须是列表的长度并且大于零。不存在的键将被忽略,除非所有键都不存在。
INFIELDS {num} {attribute} ...
将结果过滤为仅出现在文档的特定属性中的结果,例如 title 或 URL。您必须包含 num,它是您过滤所依据的属性数量。例如,如果您请求title和URL,则num为2。
RETURN {num} {identifier} AS {property} ...
限制从文档返回的属性。 num 是关键字后面的属性数量。如果 num 为 0,则其作用类似于 NOCONTENT。 identifier 是属性名称(对于哈希和 JSON)或 JSON 路径表达式(对于 JSON)。 property 是结果中使用的可选名称。如果未提供,则在结果中使用 identifier。
SUMMARIZE ...
仅返回包含匹配文本的属性部分。请参阅 突出显示 了解更多信息。
HIGHLIGHT ...
格式化匹配文本的出现。请参阅 突出显示 了解更多信息。
SLOP {slop}
是查询的术语之间允许出现的中间术语的数量。假设您正在搜索短语 你好世界。如果某些术语出现在 你好 和 世界 之间,则大于 0 的 SLOP 允许这些文本属性匹配。默认情况下,没有 SLOP 约束。
INORDER
要求文档中的术语与查询中的术语具有相同的顺序,无论它们之间的偏移量如何。通常与 SLOP 结合使用。默认为 false。
LANGUAGE {language}
在搜索查询扩展期间对所提供的语言使用词干分析器。如果查询中文文档,请设置为 chinese 以正确标记查询术语。默认为英语。如果发送不支持的语言,该命令将返回错误。请参阅 FT.CREATE 了解语言列表。如果在创建索引时指定了 LANGUAGE,则无需使用 FT.SEARCH 进行指定。
EXPANDER {expander}
使用自定义查询扩展器而不是词干分析器。请参阅 扩展。
EXPLAINSCORE
返回分数计算方式的文本描述。使用此选项需要 WITHSCORES。
PAYLOAD {payload}
添加任意二进制安全负载,该负载可暴露给自定义评分函数。请参阅 扩展。
SORTBY {attribute} [ASC|DESC] [WITHCOUNT]
按此属性的值对结果进行排序。这适用于文本和数字属性。 SORTBY 所需的属性应在索引中声明为 SORTABLE,以便以非常低的延迟可用。请注意,这会增加内存开销。
排序优化:性能针对不同场景下 DIALECT 4 上的排序操作进行了优化: - 跳过排序器 - 当没有任何类型的排序时应用。查询达到 LIMIT 请求的结果后即可返回。 - 部分范围 - 当数字字段上有 SORTBY 子句时应用,没有过滤器或按同一数字字段过滤,查询在足够大的范围上迭代以满足 LIMIT 请求的结果。 - 混合 - 当数字字段和另一个非数字过滤器上存在 SORTBY 子句时应用。某些结果将被过滤,并且初始范围可能不够大。然后迭代器按以下范围倒回,并进行额外的迭代以收集 LIMIT 请求的结果。 - 无优化 - 如果存在按分数或非数字字段排序,则除了检索所有结果并比较它们的值之外别无选择。
计算行为:可选的 WITHCOUNT 参数返回带排序的查询结果的准确计数。此操作处理所有结果以获得准确的计数,其性能低于优化选项(DIALECT 4 上的默认行为)
当与 FT.SEARCH 或 FT.AGGREGATE 一起使用时,您还可以使用 WITHOUTCOUNT 代替 DIALECT 4。
LIMIT first num
将结果限制为给定的偏移量和结果数量。请注意,偏移量是零索引的。默认值为 0 10,即从第一个结果开始返回 10 个项目。您可以使用 LIMIT 0 0 来计算结果集中的文档数量,而无需实际返回它们。
LIMIT 行为:如果使用LIMIT选项而不进行排序,则返回的结果是不确定的,这意味着后续查询可能会返回重复或缺失的值。添加具有唯一字段的 SORTBY,或将 FT.AGGREGATE 与 WITHCURSOR 选项结合使用,以确保确定性结果集分页。
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 returns an array reply.第一个元素是一个整数回复,其中包含与查询匹配的文档总数。其余元素是对:文档 ID 后跟属性值对数组。
这个总数不一定是回复中返回的文件数量。 LIMIT 控制计数后有多少匹配文档。默认为 0 10,因此包含 10 个以上匹配文档的查询返回的计数大于返回文档的数量。使用 LIMIT 0 0 仅获取总数。
例如,如果 42 个文档与查询匹配,则计数为 42,即使回复仅返回前 10 个文档:
127.0.0.1:6379> FT.SEARCH idx "@title:redis" NOCONTENT
1) (integer) 42
2) "doc:1"
3) "doc:2"
...
11) "doc:10"
127.0.0.1:6379> FT.SEARCH idx "@title:redis" LIMIT 0 0
1) (integer) 42
[!注意]
- 如果指定
NOCONTENT,该命令将返回一个数组,其中第一个元素是匹配文档的总数,其余元素是文档 ID。- 如果匹配的键过期或在查询运行时更新,Redis 在尝试加载更新的键的值时将返回空数组。该键仍算作匹配文档。
- 除非查询使用
DIALECT 4或WITHOUTCOUNT的排序优化,否则匹配文档的数量是准确的。这些查询一旦收集到LIMIT请求的结果就会停止,因此报告的数量上限为LIMIT窗口的大小,而不是计算每个匹配的文档。将WITHCOUNT添加到SORTBY子句以获得准确的计数。
返回多个值
当索引定义为 ON JSON 时,当 JSONPath 匹配多个值或当 JSONPath 匹配数组时,单个属性或单个 JSONPath 的回复可能会返回多个值。
在RediSearch v2.6之前,仅返回第一个匹配值。从 RediSearch v2.6 开始,返回所有值,并用顶级数组包装。
为了保持向后兼容性,RediSearch v2.6 的默认行为是仅返回第一个值。
要返回所有值,请使用 DIALECT 3(或更大值,如果可用)。
DIALECT 可以指定为 FT.SEARCH 命令中的参数。如果未指定,则使用 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 哈希加载文档数据并返回它们。
更复杂的查询的时间复杂度各不相同,但一般来说,它与单词的数量、单词之间的交点数量以及结果集中的结果数量成正比。
示例
Search for a term in every text attribute
在包含图书数据的索引的每个 TEXT 属性中搜索术语“向导”。
127.0.0.1:6379> FT.SEARCH books-idx“向导”
Search for a term in title attribute
在 title 属性中搜索术语 狗。
127.0.0.1:6379> FT.SEARCH books-idx "@title:dogs"
Search for books from specific years
搜索2020年或2021年出版的书籍。
127.0.0.1:6379> FT.SEARCH books-idx“@published_at:[2020 2021]”
Search for a restaurant by distance from longitude/latitude
搜索经-122.41、北纬37.77(旧金山)5公里范围内的中餐馆。
127.0.0.1:6379> FT.SEARCH餐厅-idx“中文@location:[-122.41 37.77 5公里]”
Search for a book by terms but boost specific term
在 title 属性中搜索术语 狗 或 猫,但为 狗 的匹配项提供更高的相关性分数(也称为 提升)。
127.0.0.1:6379> FT.SEARCH books-idx "(@title:dogs | @title:cats) | (@title:dogs) => { $weight: 5.0; }"
Search for a book by a term and EXPLAINSCORE
搜索索引中任何 TEXT 属性中带有 狗 的书籍,并请求对每个结果的评分进行解释。
127.0.0.1:6379> FT.SEARCH books-idx“狗”WITHSCORES EXPLAINSCORE
Search for a book by a term and TAG
搜索标题中带有 空间 且 TAG 属性 categories 中带有 science 的图书。
127.0.0.1:6379> FT.SEARCH books-idx "@title:space @categories:{science}"
Search for a book by a term but limit the number
搜索任意 TEXT 属性中带有 Python 的图书,返回整个结果集中从第 11 个结果开始的 10 个结果(offset 参数从零开始),并且每个结果仅返回 title 属性。
127.0.0.1:6379> FT.SEARCH books-idx "python" LIMIT 10 10 RETURN 1 标题
Search for a book by a term and price
搜索任意 TEXT 属性中带有 Python 的图书,返回原始 JSON 文档中存储的价格。
127.0.0.1:6379> FT.SEARCH books-idx "python" RETURN 3 $.book.price AS 价格
Search for a book by title and distance
搜索标题与 地球 语义相似的书籍。返回按距离排序的前 10 个结果。
127.0.0.1:6379> FT.SEARCH books-idx "*=>[KNN 10 @title_embedding $query_vec AS title_score]" PARAMS 2 query_vec <“行星地球”嵌入 BLOB> 排序 title_score DIALECT 2
Vector search with cluster optimization
使用集群优化搜索标题与 地球 语义相似的书籍。每个分片检索 60% 的请求结果,以提高 Redis 集群环境中的性能。有关更多信息,请参阅 查询属性 参考页。
127.0.0.1:6379> FT.SEARCH books-idx "*=>[KNN 100 @title_embedding $query_vec]=>{$SHARD_K_RATIO: 0.6; $YIELD_DISTANCE_AS: title_score}" PARAMS 2 query_vec <“行星地球”嵌入 BLOB> SORTBY title_score 方言 2
Search for a phrase using SLOP
搜索短语 你好世界。首先,创建一个索引。
127.0.0.1:6379> FT.CREATE memes SCHEMA 短语文本 OK
添加短语 你好世界 的变体。
127.0.0.1:6379> HSET s1 短语“hello world”(整数)1 127.0.0.1:6379> HSET s2 短语“hello simple world”(整数)1 127.0.0.1:6379> HSET s3 短语“hello不太简单的世界”(整数)1 127.0.0.1:6379> HSET s4 短语“你好,复杂但鼓励解决问题的世界”(整数)1 127.0.0.1:6379> HSET s5 短语“你好复杂但令人惊讶地鼓励解决问题的世界”(整数)1
然后,搜索短语 你好世界。结果返回包含该短语的所有文档。
127.0.0.1:6379> FT.SEARCH memes '@phrase:(hello world)' 无内容 1) (整数) 5 2) "s1" 3) "s2" 4) "s3" 5) "s4" 6) "s5"
现在,返回包含 你好 和 世界 之间较少单词之一的所有文档。
127.0.0.1:6379> FT.SEARCH memes '@phrase:(hello world)' 无内容 SLOP 1 1) (整数) 2 2) "s1" 3) "s2"
现在,返回 你好 和 世界 之间包含三个或更少单词的所有文档。
127.0.0.1:6379> FT.SEARCH memes '@phrase:(hello world)' NOCONTENT SLOP 3 1) (整数) 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) (整数) 4 2) "s1" 3) "s2" 4) "s3" 5) "s4"
如果您添加其他术语(和词干),您将得到这些结果。
127.0.0.1:6379> FT.SEARCH memes '@phrase:(hello Amazing world)' NOCONTENT 1) (整数) 1 2) "s5"
127.0.0.1:6379> FT.SEARCH memes '@phrase:(你好,鼓励世界)' NOCONTENT SLOP 5 1) (整数) 2 2) "s4" 3) "s5"
127.0.0.1:6379> FT.SEARCH memes '@phrase:(你好,鼓励世界)' NOCONTENT SLOP 4 1) (整数) 1 2) "s4"
如果您交换术语,您仍然可以检索到正确的短语。
127.0.0.1:6379> FT.SEARCH memes '@phrase:(amazing hello world)' NOCONTENT 1) (整数) 1 2) "s5"
但是,如果您使用 INORDER,您将得到零结果。
127.0.0.1:6379> FT.SEARCH memes '@phrase:(amazing hello world)' NOCONTENT INORDER 1) (整数) 0
同样,如果您使用设置为 true 的查询属性 $inorder,则不会检索 s5。
127.0.0.1:6379> FT.SEARCH memes '@phrase:(amazing hello world)=>{$inorder: true;}' NOCONTENT 1) (整数) 0
总而言之,INORDER 参数或 $inorder 查询属性要求查询术语与具有相似顺序的术语相匹配。
Polygon Search with WITHIN, CONTAINS, INTERSECTS, and DISJOINT operators
查询多边形:
- 包含给定的地理形状
- 在给定的地理形状内
- 与给定的地理形状相交
- 与给定形状不相交(没有共同点)
v2.10 中引入了 INTERSECTS 和 DISJOINT。
首先,使用 GEOSHAPE 类型和 FLAT 坐标系创建索引:
127.0.0.1:6379> FT.CREATE idx SCHEMA geom GEOSHAPE 平面确定
使用 HSET 添加几个几何图形:
127.0.0.1:6379> HSET 小几何图形 'POLYGON((1 1, 1 100, 100 100, 100 1, 1 1))' (整数) 1 127.0.0.1:6379> HSET 大几何图形 'POLYGON((1 1, 1 200, 200) 200, 200 1, 1 1))'(整数)1
使用WITHIN运算符查询:
127.0.0.1:6379> FT.SEARCH idx '@geom:[WITHIN $poly]' PARAMS 2 聚 'POLYGON((0 0, 0 150, 150 150, 150 0, 0 0))' 方言 3
1) (整数) 1 2) “小” 3) 1) “几何” 2) “多边形((1 1, 1 100, 100 100, 100 1, 1 1))”
使用CONTAINS运算符查询:
127.0.0.1:6379> FT.SEARCH idx '@geom:[包含 $poly]' PARAMS 2 聚 'POLYGON((2 2, 2 50, 50 50, 50 2, 2 2))' 方言 3
1) (整数) 2 2) “小” 3) 1) “几何” 2) “多边形((1 1, 1 100, 100 100, 100 1, 1 1))” 4) “大” 5) 1) “几何” 2) “多边形((1 1, 1 200, 200) 200, 200 1, 1 1))"
Redis Software 与 Redis Cloud 兼容性
| Redis 软件 |
Redis软件 Flex |
Redis Cloud 灵活且每年 |
Redis Cloud 免费和固定 |
说明 |
|---|---|---|---|---|
| ✅ 支持 | ✅ 支持 | ✅ 支持 | ✅ 支持 |
返回值
RESP2
以下之一: * 数组:第一个元素是与查询匹配的文档总数。其余元素是文档 ID,后跟其字段值对(数组)。回复中返回的文档数量受到LIMIT的限制,因此往往小于匹配文档的总数。 * 简单错误回复 在这些情况下:没有这样的索引,查询中有语法错误。
RESP3
以下之一: * 地图 具有以下字段: - total_results:整数 - 与查询匹配的文档总数,无论 results 返回多少个 - results:包含文档信息的 地图 的 数组,受 LIMIT 限制 - attributes:属性名称的 数组 - format: 简单字符串 - 结果格式 - warning:警告消息的 数组 * 简单错误回复 在这些情况下:没有这样的索引,查询中存在语法错误。
参见
相关主题
资料来源:Redis 官方 FT.SEARCH 文档;中文内容参考 Redis 文档许可。