*Redis FT.SEARCH 命令

FT.SEARCH 用于在 RediSearch 索引中执行全文搜索查询,支持复杂的布尔查询、范围过滤、排序和分页。


*语法

FT.SEARCH index_name 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] [INKEYS count key [key ...]] [INFIELDS count field [field ...]] [RETURN count field [field ...]] [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 lang] [EXPANDER expander] [SCORER scorer] [SORTBY field [ASC|DESC] [WITHCOUNT]] [LIMIT offset num] [PARAMS count name value [name value ...]] [DIALECT dialect] [EXPPLAINSCORE]

*参数说明

参数 类型 必填 说明
index_name String 索引名称
query String 搜索查询表达式
NOCONTENT Flag 仅返回文档 ID,不返回字段内容
VERBATIM Flag 禁用词干提取和扩展
NOSTOPWORDS Flag 不忽略停用词
WITHSCORES Flag 返回相关性评分
WITHPAYLOADS Flag 返回 payloads(仅 Legacy 模式)
WITHSORTKEYS Flag 返回排序键值
FILTER 条件 对数值字段进行范围过滤
GEOFILTER 条件 对 GEO 字段进行地理范围过滤
INKEYS 条件 限制仅在指定 key 中搜索
INFIELDS 条件 限制仅在指定字段中搜索
RETURN 条件 指定返回的字段列表
SUMMARIZE 条件 返回字段摘要(片段)
HIGHLIGHT 条件 高亮匹配的关键词
SLOP Integer 短语查询中词项之间的最大距离
TIMEOUT Integer 查询超时时间(毫秒)
INORDER Flag 要求词项按查询中的顺序出现
LANGUAGE String 指定语言(用于词干提取)
EXPANDER String 指定查询扩展器
SCORER String 指定评分算法(TFIDF、BM25、DISMAX 等)
SORTBY 条件 按指定字段排序
LIMIT 分页 分页参数(offset num)
PARAMS 参数 绑定查询参数(用于 Dialect 2+)
DIALECT Integer 查询方言版本(1、2、3、4)
EXPLAINSCORE Flag 解释评分计算过程

*返回值

  • 查询结果数组
    • 第一个元素:总匹配数量(或 LIMIT 前的结果数,取决于 Dialect)
    • 后续元素:每个文档结果(文档 ID + 字段内容)
  • 若使用 NOCONTENT:仅返回文档 ID
  • 若使用 WITHSCORES:每个文档后跟随评分值
  • 空查询或无结果:返回 1) (empty array) 或仅包含 0 的数组

*时间复杂度

O(n),其中 n 是查询结果数量。实际复杂度取决于查询条件、索引结构和过滤条件。


*示例

*基本搜索

> FT.SEARCH myIndex "hello world"
1) "1"
2) "doc:100"
3) 1) "title"
   2) "hello world example"
   3) "content"
   4) "this is a hello world article about redis"

*带过滤条件的搜索

> FT.SEARCH myIndex "redis" FILTER price 10 100 SORTBY price ASC LIMIT 0 10
1) "3"
2) "doc:200"
3) 1) "title"
   2) "redis tutorial"
   3) "price"
   4) "25"
4) "doc:201"
5) 1) "title"
   2) "advanced redis"
   3) "price"
   4) "50"
6) "doc:202"
7) 1) "title"
   2) "redis search guide"
   3) "price"
   4) "75"

*使用 Dialect 2 进行参数化查询

> FT.SEARCH myIndex "@title:$keyword" PARAMS 2 keyword "redis" DIALECT 2
1) "2"
2) "doc:100"
3) 1) "title"
   2) "redis search"
   3) "content"
   4) "redis search module"
4) "doc:101"
5) 1) "title"
   2) "redis tutorial"
   3) "content"
   4) "redis basics"

*常见错误

错误 原因 解决
Syntax error at offset ... 查询语法错误 检查查询表达式的引号、括号匹配
Unknown index name 索引不存在 确认索引已创建,名称拼写正确
Property 'xxx' not loaded 字段未加载 使用 RETURN 指定字段,或检查索引中是否定义了该字段
GEO filter invalid 地理过滤参数错误 检查经纬度范围和半径单位(m/km/mi/ft)
Timeout limit reached 查询超时 增加 TIMEOUT 参数,或优化查询条件
Missing param 'xxx' 参数化查询缺少参数 检查 PARAMS 是否正确定义

*最佳实践

  • 生产环境推荐使用 Dialect 2 或更高版本,支持参数化查询和更丰富的语法
  • 对大数据量查询使用 LIMIT 分页,避免一次性返回过多结果
  • 使用 NOCONTENT 仅需文档 ID 时减少数据传输
  • 对高频查询字段设置 SORTABLE 属性以优化排序性能
  • 使用 FILTER 替代数值范围查询,性能更优
  • 短语查询使用双引号,如 "exact phrase"
  • 使用 @field:term 语法限定字段搜索,提升精确度和性能
  • 设置合理的 TIMEOUT 防止慢查询影响系统

*FAQ

Q1: FT.SEARCH 和 FT.AGGREGATE 有什么区别? A: FT.SEARCH 用于搜索并返回文档内容,FT.AGGREGATE 用于数据聚合(分组、统计、计算)。FT.SEARCH 底层也会使用聚合管道,但语法更简洁,专注于返回文档。

Q2: 为什么总匹配数有时不准确? A: 在 Dialect 1 中,LIMIT 前的总匹配数可能不精确(近似值)。使用 Dialect 2+ 或设置 WITHCOUNT 可获得精确计数,但性能开销更大。

Q3: 如何实现 OR 和 AND 查询? A: 默认词项之间是 OR 关系(如 hello world 匹配 hello 或 world)。使用 | 显式表示 OR,hello | world。AND 使用空格或 &(Dialect 2+)。否定使用 -(如 hello -world)。

Q4: 支持中文搜索吗? A: 支持。对于中文,建议使用 Dialect 2+ 的 PARAMS 参数化查询,并注意中文分词需要合理配置。可在创建索引时通过 LANGUAGE 指定 chinese(如果底层支持)。