大家好,欢迎来到今天的 Redis Search (RediSearch) 高级索引与查询语法“脱口秀”!我是你们今天的“段子手”兼技术指导。今天咱们不搞虚的,直接上干货,保证让大家听完之后,感觉 Redis Search 不再是“别人家的孩子”,而是你手中一把锋利的“屠龙刀”。
第一幕:索引的艺术 – 超越基础,玩转高级索引
首先,咱们来聊聊索引。别以为索引就是简单的 FT.CREATE
一下,然后就万事大吉了。RediSearch 的索引可是个“百变怪”,可以根据你的需求,变出各种花样。
-
SCHEMA
的进阶之路SCHEMA
定义了你的索引结构,决定了哪些字段可以被搜索。 除了基本的TEXT
、NUMERIC
、TAG
之外,还有很多高级选项等着你:-
WEIGHT
加权: 想象一下,你的商品描述里,商品名称的重要性肯定比“颜色”要高吧?WEIGHT
就是用来控制这个的。FT.CREATE my_index SCHEMA product_name TEXT WEIGHT 5.0 description TEXT WEIGHT 1.0 color TAG
这样,搜索
红色
时,商品名称包含“红色”的商品,排名会更靠前。 -
SORTABLE
排序: 有些字段你可能需要用来排序,比如价格、评分等等。 加上SORTABLE
之后,就可以使用SORTBY
命令进行排序了。FT.CREATE my_index SCHEMA product_name TEXT description TEXT price NUMERIC SORTABLE rating NUMERIC SORTABLE
-
NOINDEX
不索引: 有些字段你可能只需要存储,不需要搜索。 比如用户 ID、创建时间等等。 加上NOINDEX
可以节省空间,提高性能。FT.CREATE my_index SCHEMA product_name TEXT description TEXT user_id NUMERIC NOINDEX created_at NUMERIC NOINDEX
-
WITHSUFFIXTRIE
后缀 Trie 优化: 对于前缀搜索,RediSearch 使用 Trie 结构。 加上WITHSUFFIXTRIE
可以进一步优化,特别是对于大量相似字符串的场景。FT.CREATE my_index SCHEMA product_name TEXT WITHSUFFIXTRIE
-
PHONETIC
语音搜索: 这个就厉害了,可以根据发音来搜索。 比如你输入“苹果”,它能找到“Apple”。 支持多种语言。FT.CREATE my_index SCHEMA product_name TEXT PHONETIC dm:en description TEXT
这里
dm:en
代表德语-英语语音编码算法。
举个例子
假设我们要创建一个电商商品的索引,包含商品名称、描述、价格、评分、颜色、品牌、以及创建时间。 我们希望商品名称权重高,价格和评分可以排序,颜色和品牌用标签搜索,创建时间不需要索引。
FT.CREATE product_index SCHEMA product_name TEXT WEIGHT 5.0 description TEXT price NUMERIC SORTABLE rating NUMERIC SORTABLE color TAG brand TAG created_at NUMERIC NOINDEX
-
-
PREFIX
前缀:PREFIX
指定了哪些 key 需要被索引。 默认情况下,RediSearch 会索引所有 key。 但通常我们只会索引特定前缀的 key,比如product:
。FT.CREATE product_index PREFIX 1 product: SCHEMA ...
这样,只有以
product:
开头的 key 才会被索引。 -
FILTER
过滤器:FILTER
允许你在索引时过滤数据。 只有满足条件的 key 才会添加到索引。 可以使用 Redis 的表达式语言进行过滤。FT.CREATE product_index SCHEMA ... FILTER '@price > 100 && @rating > 4.5'
只有价格大于 100 且评分大于 4.5 的商品才会被索引。
-
LANGUAGE
语言: 指定索引的语言。 RediSearch 会根据语言进行分词、词干提取等处理。FT.CREATE product_index SCHEMA product_name TEXT LANGUAGE chinese description TEXT LANGUAGE english
这里,商品名称使用中文分词,描述使用英文分词。
第二幕:查询的魔法 – 精准搜索,玩转高级查询语法
索引建好了,接下来就是查询了。 RediSearch 的查询语法非常强大,可以实现各种复杂的搜索需求。
-
基本语法回顾:
*
: 匹配所有term
: 匹配包含 term 的文档-term
: 排除包含 term 的文档|
: 或关系()
: 优先级
-
高级查询技巧:
-
@field:value
指定字段查询: 指定在某个字段中搜索。FT.SEARCH product_index "@product_name:苹果"
只在
product_name
字段中搜索 "苹果"。 -
FUZZY {Levenshtein Distance}
模糊搜索: 允许一定的拼写错误。FT.SEARCH product_index "%appl%" FUZZY 1
允许一个字符的拼写错误。
-
PHRASE
短语搜索: 搜索完整的短语。FT.SEARCH product_index '"红色 苹果"' PHRASE
搜索包含 "红色 苹果" 这个完整短语的文档。
-
TAG
标签搜索: 搜索标签字段。FT.SEARCH product_index "@color:{红色}"
搜索
color
字段包含 "红色" 标签的文档。 可以使用|
和-
进行标签的或和排除。 -
NUMERIC
数值范围搜索: 搜索数值字段的范围。FT.SEARCH product_index "@price:[100 200]"
搜索
price
字段在 100 到 200 之间的文档。 可以使用(
和)
表示开区间。 -
GEO
地理位置搜索: 搜索地理位置附近的文档。FT.SEARCH geo_index "@location:[-122.4194 37.7749 10 km]"
搜索
location
字段距离经纬度 (-122.4194, 37.7749) 10 公里范围内的文档。 -
SORTBY
排序: 按照指定字段排序。FT.SEARCH product_index "*" SORTBY price DESC
按照
price
字段降序排序。 -
LIMIT
分页: 限制返回结果的数量。FT.SEARCH product_index "*" LIMIT 0 10
返回第 0 到 9 条记录。
-
RETURN
返回指定字段: 只返回指定的字段。FT.SEARCH product_index "*" RETURN 1 product_name 1 price
只返回
product_name
和price
字段。 -
SUMMARIZE
摘要: 生成文本字段的摘要。FT.SEARCH product_index "苹果" SUMMARIZE
生成包含 "苹果" 的文本字段的摘要。
-
HIGHLIGHT
高亮: 高亮显示搜索关键词。FT.SEARCH product_index "苹果" HIGHLIGHT
高亮显示包含 "苹果" 的关键词。
-
INKEYS
指定 Key 查询: 只在指定的 key 中搜索。FT.SEARCH product_index "*" INKEYS 2 product:123 product:456
只在
product:123
和product:456
这两个 key 中搜索。 -
INFIELDS
指定字段查询 (多个): 只在指定的多个字段中搜索.FT.SEARCH product_index "苹果" INFIELDS 2 product_name description
只在
product_name
和description
字段中搜索 "苹果"。 -
DIALECT
指定查询语法版本: RediSearch 的查询语法在不断更新,使用DIALECT
可以指定使用的语法版本。FT.SEARCH product_index "*" DIALECT 2
-
-
组合查询: 可以将以上技巧组合起来,实现更复杂的搜索需求。
举个例子
假设我们要搜索价格在 100 到 200 之间,评分大于 4.5,颜色是红色或蓝色的商品,按照评分降序排序,返回商品名称和价格,高亮显示关键词。
FT.SEARCH product_index "@price:[100 200] @rating:(4.5 inf] @color:{红色|蓝色}" SORTBY rating DESC RETURN 2 product_name price HIGHLIGHT
第三幕:实战演练 – 电商搜索场景
光说不练假把式,咱们来模拟一个电商搜索场景,把上面学到的东西用起来。
假设我们有以下商品数据:
商品 ID | 商品名称 | 描述 | 价格 | 评分 | 颜色 | 品牌 |
---|---|---|---|---|---|---|
1 | 红色 苹果 | 新鲜的红富士苹果 | 120 | 4.8 | 红色 | 苹果 |
2 | 蓝色 三星手机 | 性能强大的三星 Galaxy S23 | 6999 | 4.7 | 蓝色 | 三星 |
3 | 绿色 小米手环 | 智能健康手环 | 249 | 4.6 | 绿色 | 小米 |
4 | 黑色 华为平板 | 高清大屏华为 MatePad Pro | 3999 | 4.9 | 黑色 | 华为 |
5 | 金色 iPhone 14 | 拍照强大的 iPhone 14 | 7999 | 4.5 | 金色 | 苹果 |
首先,创建索引:
FT.CREATE product_index SCHEMA
product_name TEXT WEIGHT 5.0
description TEXT
price NUMERIC SORTABLE
rating NUMERIC SORTABLE
color TAG
brand TAG
然后,将数据添加到 Redis:
HSET product:1 product_name "红色 苹果" description "新鲜的红富士苹果" price 120 rating 4.8 color "红色" brand "苹果"
HSET product:2 product_name "蓝色 三星手机" description "性能强大的三星 Galaxy S23" price 6999 rating 4.7 color "蓝色" brand "三星"
HSET product:3 product_name "绿色 小米手环" description "智能健康手环" price 249 rating 4.6 color "绿色" brand "小米"
HSET product:4 product_name "黑色 华为平板" description "高清大屏华为 MatePad Pro" price 3999 rating 4.9 color "黑色" brand "华为"
HSET product:5 product_name "金色 iPhone 14" description "拍照强大的 iPhone 14" price 7999 rating 4.5 color "金色" brand "苹果"
接下来,进行各种搜索:
-
搜索包含 "苹果" 的商品:
FT.SEARCH product_index "苹果"
-
搜索价格在 100 到 500 之间的商品:
FT.SEARCH product_index "@price:[100 500]"
-
搜索颜色是红色或蓝色的商品:
FT.SEARCH product_index "@color:{红色|蓝色}"
-
搜索品牌是苹果的商品,按照评分降序排序:
FT.SEARCH product_index "@brand:{苹果}" SORTBY rating DESC
-
搜索包含 "手机" 的商品,返回商品名称和描述,高亮显示关键词:
FT.SEARCH product_index "手机" RETURN 2 product_name description HIGHLIGHT
第四幕:性能优化 – 让搜索飞起来
RediSearch 性能已经很好了,但我们还可以进一步优化。
- 合理设计
SCHEMA
: 只索引需要的字段,避免过度索引。 - 使用
NOINDEX
: 对于不需要搜索的字段,使用NOINDEX
。 - 使用
WITHSUFFIXTRIE
: 对于前缀搜索,使用WITHSUFFIXTRIE
。 - 批量索引: 使用
FT.ADDHASH
和FT.ADD
命令批量添加数据。 - 使用 Pipeline: 将多个查询命令放入 Pipeline 中执行。
- 监控性能: 使用
FT.INFO
命令监控索引状态和查询性能。 - 合理分片: 如果数据量太大,可以考虑将索引分片到多个 Redis 实例上。
表格总结常用查询语法
查询类型 | 语法 | 示例 | 描述 |
---|---|---|---|
关键词搜索 | term |
FT.SEARCH my_index "apple" |
搜索包含 "apple" 的文档 |
排除关键词 | -term |
FT.SEARCH my_index "-apple" |
搜索不包含 "apple" 的文档 |
或关系 | term1 | term2 |
FT.SEARCH my_index "apple | orange" |
搜索包含 "apple" 或 "orange" 的文档 |
指定字段搜索 | @field:value |
FT.SEARCH my_index "@title:apple" |
在 "title" 字段中搜索 "apple" |
模糊搜索 | %term% FUZZY {Levenshtein Distance} |
FT.SEARCH my_index "%appl%" FUZZY 1 |
允许一个字符的拼写错误搜索 "appl" |
短语搜索 | "{phrase}" PHRASE |
FT.SEARCH my_index '"red apple" PHRASE' |
搜索包含 "red apple" 这个完整短语的文档 |
标签搜索 | @field:{tag1 | tag2} |
FT.SEARCH my_index "@color:{red|blue}" |
搜索 "color" 字段包含 "red" 或 "blue" 标签的文档 |
数值范围搜索 | @field:[min max] |
FT.SEARCH my_index "@price:[10 100]" |
搜索 "price" 字段在 10 到 100 之间的文档 |
地理位置搜索 | @field:[longitude latitude radius unit] |
FT.SEARCH my_index "@location:[-122.4 37.8 10 km]" |
搜索 "location" 字段距离经纬度 (-122.4, 37.8) 10 公里范围内的文档 |
排序 | SORTBY field ASC|DESC |
FT.SEARCH my_index "*" SORTBY price DESC |
按照 "price" 字段降序排序 |
分页 | LIMIT offset num |
FT.SEARCH my_index "*" LIMIT 0 10 |
返回第 0 到 9 条记录 |
返回指定字段 | RETURN num field1 field2 ... |
FT.SEARCH my_index "*" RETURN 1 title |
只返回 "title" 字段 |
摘要 | SUMMARIZE |
FT.SEARCH my_index "apple" SUMMARIZE |
生成包含 "apple" 的文本字段的摘要 |
高亮 | HIGHLIGHT |
FT.SEARCH my_index "apple" HIGHLIGHT |
高亮显示包含 "apple" 的关键词 |
指定Key查询 | INKEYS num key1 key2 ... |
FT.SEARCH my_index "*" INKEYS 2 doc1 doc2 |
只在 "doc1" 和 "doc2" 这两个 key 中搜索 |
指定字段查询(多) | INFIELDS num field1 field2 ... |
FT.SEARCH my_index "apple" INFIELDS 2 title content |
只在 "title" 和 "content" 字段中搜索 "apple" |
指定语法版本 | DIALECT version |
FT.SEARCH my_index "*" DIALECT 2 |
使用 RediSearch 2.0 查询语法 |
第五幕:总结与展望 – 星辰大海,未来可期
今天我们一起探索了 RediSearch 的高级索引与查询语法,从 SCHEMA
的进阶之路到各种高级查询技巧,再到实战演练和性能优化,相信大家对 RediSearch 已经有了更深入的了解。
RediSearch 的功能还在不断完善,未来会有更多惊喜等着我们。 比如向量相似度搜索、机器学习集成等等。 让我们一起期待 RediSearch 的未来,也期待大家在实际项目中灵活运用 RediSearch,创造更多价值!
好了,今天的“脱口秀”就到这里。 感谢大家的收听! 如果有什么问题,欢迎随时提问。 我们下期再见!