发现一个好玩且性能很高的数据查询方式,可以进行数据查询筛选聚合,也具备全文搜索引擎的功能
准备
使用docker快速搭建,镜像为redis/redis-stack:7.0.2-RC1,其中RedisJSON版本为2.2.0,RediSearch版本为2.4.11
1 | docker run -d --name redis-stack -p 6379:6379 --restart=always \ |
准备数据
1 | JSON.SET phone:1 $ '{"name": "锤子8plus","description": "锤子手机-5G-128G","brandName":"锤子","price": 3299, "keyword":["锤子","plus","锤子8"]}' |
建立索引
1 | FT.CREATE idx_test ON JSON PREFIX 1 'phone:' LANGUAGE chinese SCHEMA $.name AS name TEXT $.description as description TEXT $.brandName AS brandName TAG $.price AS price NUMERIC SORTABLE $.keyword.* as keyword TAG |
搜索
RediSearch搜索中TEXT内容会全文搜索,以关键词的形式进行搜索。如‘@name:华为’能搜索到3条记录,但如果进行‘@name:华为Mate40’的搜索却一条也搜索不到,因为RediSearch认为“华为”和“Mate40”是两个词。
查询所有数据
1 | FT.SEARCH idx_test * |
搜索name字段中包含“华为”关键词的数据
1 | FT.SEARCH idx_test '@name:华为' |
搜索name字段中包含“华为”和“Mate40”关键词的数据
1 | FT.SEARCH idx_test '@name:(华为 Mate40)' |
搜索name字段中包含“华为”或“锤子”关键词的数据
1 | FT.SEARCH idx_test '@name:(华为|锤子)' |
搜索name字段中包含“华为”关键词且价格在3000到6000的数据
1 | FT.SEARCH idx_test '@name:华为 @price:[3000, 6000]' |
模糊搜索
搜索name字段中包含开头为“华”的数据(但默认情况下不能使用“*为”进行前缀匹配,需要修改配置)
1 | FT.SEARCH idx_test '@name:华*' |
搜索name字段中包含“Mate50”的数据,对LD为1的所有关键词进行模糊匹配,所以这里能搜索到Mate40和Mate30的数据
1 | FT.SEARCH idx_test '@name:%Mate50%' |
搜索name字段中包含“Qate51”的数据,对LD为3的所有关键词进行模糊匹配,所以这里能搜索到Mate40和Mate30的数据
1 | FT.SEARCH idx_test '@name:%%%Qate51%%%' |
使用通配符,目前版本感觉存在问题
1 | FT.SEARCH idx_test @description:w'vivo?128G' |
聚合查询
每千元一个挡位进行分组
1 | FT.AGGREGATE idx_test * |
排序分页
按价格排序,只查询出name和price字段
1 | FT.SEARCH idx_test * RETURN 2 name price name SORTBY price DESC |
按价格排序,只查询出name和price字段,从第3条开始,查询2条数据
1 | FT.SEARCH idx_test * RETURN 2 name price LIMIT 3 2 SORTBY price DESC |
分词
rediSearch会将TEXT类型内容进行简单的分词(且忽略大小写),比如搜索“华为”或“Mate40”或“mate40”都能出现“华为Mate40 pro”这条数据,但分词效果一般,用“Mate”或“华为Mate40”搜索不到数据。
1.可以自定义词库的方法进行优化,这里就不介绍了。
2.使用空格或横线等方式让rediSearch对内容进行分词,从而达到想要的搜索效果,比如本次测试数据中的description字段
搜索description字段中包含“5G”关键词的数据
1 | FT.SEARCH idx_test '@description:5G' |
3.使用数组搜索,将分好的关键词放入其中数组中
测试使用的是TAG类型进行数组搜索,TAG类型搜索时并不会分词(但同样忽略大小写),必须完全相等才能匹配。
搜索keyword数组中包含“华为”和“Mate”的数据
1 | FT.SEARCH idx_test '@keyword:{华为} @keyword:{Mate}' |
搜索keyword数组中包含“华为”或“Mate”的数据
1 | FT.SEARCH idx_test '@keyword:{华为|Mate}' |
参考文献
- RediSearch查询语法:https://redis.io/docs/stack/search/reference/query_syntax/
- RediRearch索引JSON:https://redis.io/docs/stack/search/indexing_json/
- RedisJSON路径:https://redis.io/docs/stack/json/path/
- redisearch+redisJSON联合使用:https://blog.csdn.net/qq_48078182/article/details/126130818
- redisearch+springboot的简单使用:https://blog.csdn.net/qq_48078182/article/details/126016811
- RedisJson和RedisSearch探究:https://blog.csdn.net/hebeiqiaozhonghui/article/details/122739332