Redis全文搜索教程之创建索引并关联源数据的教程

 更新时间:2023年12月21日 09:03:20   作者:waynaqua  
RediSearch提供了一种简单快速的方法对 hash 或者 json 类型数据的任何字段建立二级索引,然后就可以对被索引的 hash 或者 json 类型数据字段进行搜索和聚合操作,这篇文章主要介绍了Redis全文搜索教程之创建索引并关联源数据,需要的朋友可以参考下

Redis 全文搜索是依赖于 Redis 官方提供的 RediSearch 来实现的。RediSearch 提供了一种简单快速的方法对 hash 或者 json 类型数据的任何字段建立二级索引,然后就可以对被索引的 hash 或者 json 类型数据字段进行搜索和聚合操作。

这里我们把被索引的 hash 或者 json 类型数据叫做源数据。

本文大纲如下,

使用体验

简单场景下,用 RediSearch 来平替 Elasticsearch 的使用场景已经足够。像是 Elasticsearch 中常用的查询语法 AND 、OR 、IN 、NOT IN 、> 、< 、= 、like 等,在 RediSearch 中都是支持的。

此外 RediSearch 还支持聚合统计、停用词、文本标记和转义、同义词、标签、排序、向量查询、中文分词等。

就我个人来说,个人项目使用 RediSearch 作为全文搜索引擎已经够用了,它有占用内存低、索引建立快、查询数据性能足够高等优点。

后续发展

就目前官方对 RediSearch 的支持更新来看,

最近一次提交记录在 12 月 17 号。

可以看到 RediSearch 的更新频率还是比较高的,而且是官方支持做的模块,不用担心后续无人维护。

虽然 Redis 天生支持分布式集群,但是 RediSearch 对 Redis 集群的支持还不完善,引用官方说明,

官方针对 RediSearch 的集群支持问题,提供了一个 RediSearch 集群版本,但是这个版本只能在 Redis 企业版或者 Redis Cloud 上能使用,开源版还没有,这一点需要告诉大家。

遇到 bug

首先在使用 RediSearch 的过程中,遇到了 bug 并发现 bug 来源于 RediSearch,不要慌,也不要抱怨难用, 毕竟是开源项目,

大家可以看到 issue 列表中有很多 bug 没有解决。

不过本着开源共进的精神,希望大家发现了 bug 后,第一时间在 RediSearch 官方 github 上提个 issue,方便官方发现并解决问题。

RediSearch Github 仓库地址:https://github.com/RediSearch/RediSearch

下面我给大家用 newbee-mall-pro 项目作为样本,给大家介绍下如何创建一个索引并关联源数据。

newbee-mall-pro 项目地址:https://github.com/wayn111/newbee-mall-pro

添加源数据

在 newbee-mall-pro 项目中,已经将商品数据以 hash 类型存入了 Redis 中,

其中,我们对于 key 名称的定义规则是按照 newbee_mall:goods: + 商品ID

这里我们的 key 名称定义规则很重要,RediSearch 创建索引会基于 key 名称前缀来生成。

hash 类型的 value 包含属性如下,

  • goodsId : 商品 ID,唯一属性,由数据库商品表主键生成
  • goodsName : 商品名称
  • goodsIntro : 商品简介
  • goodsCategoryId : 商品分类 ID,唯一属性,由数据库商品分类表主键生成
  • goodsSellStatus : 商品上架状态,0 代表下架,1 代表上架
  • sellingPrice : 商品售价
  • originalPrice : 商品原价
  • tag : 商品标签

在 newbee-mall-pro 中,添加源数据的方法已经写好了,代码逻辑在 JedisSearch.addGoodsListIndex() 方法里,

public boolean addGoodsListIndex(String keyPrefix, List<Goods> list) {
    int chunk = 200;
    List<List<Goods>> partition = ListUtil.partition(list, chunk);
    AbstractPipeline pipelined = client.pipelined();
    for (List<Goods> goodsList : partition) {
        for (Goods goods : goodsList) {
            RsGoodsDTO target = new RsGoodsDTO();
            MyBeanUtil.copyProperties(goods, target);
            Map<String, String> hash = MyBeanUtil.toMap(target);
            // 支持中文
            hash.put("_language", Constants.GOODS_IDX_LANGUAGE);
            pipelined.hset(keyPrefix + goods.getGoodsId(), hash);
        }
    }
    pipelined.sync();
    return true;
}

上诉代码中,其实就是把 list 商品列表以 hash 类型的数据结构写进 Redis 中,并且为了加快写入速度,使用了 Redis 提供的管道操作。

需要注意的就是 hash 类型中新增了一个 _language 字段,用于指定 RediSearch 对于源数据关联的索引,要使用中文分词查询。

建立索引

RediSearch 通过提供一种简单且自动的方式在 Redis hash 类型数据结构上创建二级索引,并且内部极大地简化了这一过程。(最终会出现更多数据结构)

如果我们要使用 RediSearch 查询商品 hash 结构里的 goodsName 字段,那么必须要对该字段建立索引。

Jedis 新建索引

所以这里,我给大家介绍下在 newbee-mall-pro 项目中,是如何建立索引的,代码逻辑在 GoodsServiceImpl.syncRs() 方法中,

// 定义索引结构
public boolean syncRs() {
    jedisSearch.dropIndex("idx:goods");
    Schema schema = new Schema()
            .addSortableTextField("goodsName", 1.0)
            .addSortableTextField("goodsIntro", 0.5)
            .addSortableNumericField("goodsId")
            .addSortableNumericField("goodsCategoryId")
            .addSortableNumericField("goodsSellStatus")
            .addSortableNumericField("sellingPrice")
            .addSortableNumericField("originalPrice")
            .addSortableTagField("tag", "|");
    jedisSearch.createIndex(Constants.GOODS_IDX_NAME, Constants.GOODS_IDX_PREFIX, schema);
}

上述代码中,我们对商品 hash 结构里的下方字段都建立了索引。

  • goodsName:文本类型,可排序,设置权重为 1.0
  • goodsIntro:文本类型,可排序,设置权重为 0.5
  • goodsId:数字类型,可排序
  • goodsCategoryId:数字类型,可排序
  • goodsSellStatus:数字类型,可排序
  • sellingPrice:数字类型,可排序
  • originalPrice:数字类型,可排序
  • tag:标签类型,可排序,设置分隔符为字符串 |

在 RediSerach 中可以添加的字段类型有 text、numberic、tag 等,可以设置是否排序。

并且还可以设置权重系数,表示该字段已加权。这对于在搜索操作期间为特定字段分配不同的重要性级别非常有用,通常就是在条件筛选完成后的打分排序阶段用于提升或者降低排名。

Redis 中的新建索引语法

当我们把上面的 Jedis 新建索引的代码转换为 Redis 中的语法后,如下

> FT.CREATE idx:goods ON hash PREFIX 1 "newbeemall:goods:" \
SCHEMA goodsName TEXT SORTABLE WEIGHT 1.0 \
SCHEMA goodsIntro TEXT SORTABLE WEIGHT 0.5 \
goodsId NUMERIC SORTABLE \
goodsCategoryId NUMERIC SORTABLE \
goodsSellStatus NUMERIC SORTABLE \
sellingPrice NUMERIC SORTABLE \
originalPrice NUMERIC SORTABLE \
tag TAG SORTABLE SEPARATOR "|"

现在我给大家详细介绍下这条命令:

  • FT.CREATE:RediSearch 中索引创建语法。
  • idx:goods:指定索引名称,索引名称将在所有键名称中使用,因此请保持简短。
  • ON hash:指定索引关联的结构类型。需要注意的是,在 RediSearch 2.0 中仅支持哈希结构,随着 RediSearch 更新,后续有望支持更多数据结构。
  • PREFIX 1 "newbeemall:goods:":指定索引的关联源数据的 key 前缀,可以指定多个前缀。
  • SCHEMA ...:字段定义,用于定义字段名称、类型、是否排序、权重等。可以定义多个字段。

如果你想了解更多关于 ft.search 的语法以及字段定义相关的只是,可以打开官方文档,

https://redis.io/docs/interact/search-and-query/basic-constructs/schema-definition

Redis 中查询索引定义

在 RediSearch 中要查询已经存在的索引详情也是很简单的,官方提供了 ft.info 索引名称 的语法,用来打印索引详情。

> FT.INFO idx:goods

最后聊两句

本文给大家用我的开源项目 newbee-mall-pro 作为样本,给大家细致的介绍了一番 RediSearch 在项目实战中关于索引创建与关联源数据的用法,希望大家喜欢。

到此这篇关于Redis全文搜索教程之创建索引并关联源数据的文章就介绍到这了,更多相关Redis创建索引并关联源数据内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • redis中Could not get a resource from the pool异常及解决方案

    redis中Could not get a resource from

    这篇文章主要介绍了redis中Could not get a resource from the pool异常及解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-12-12
  • Redisson实现分布式锁、锁续约的案例

    Redisson实现分布式锁、锁续约的案例

    这篇文章主要介绍了Redisson如何实现分布式锁、锁续约,本文通过示例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-03-03
  • Redis 删除策略的三种实现

    Redis 删除策略的三种实现

    本文主要介绍了Redis 删除策略的三种实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-06-06
  • redis中5种数据基础查询命令

    redis中5种数据基础查询命令

    本文主要介绍了redis中5种数据基础查询命令,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-04-04
  • redis键空间通知使用实现

    redis键空间通知使用实现

    这篇文章主要介绍了redis键空间通知使用实现
    2021-08-08
  • Redis increment 函数处理并发序列号案例

    Redis increment 函数处理并发序列号案例

    这篇文章主要介绍了Redis increment 函数处理并发序列号案例,本文通过实例代码给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧
    2024-08-08
  • redis实现加锁的几种方法示例详解

    redis实现加锁的几种方法示例详解

    这篇文章主要给大家介绍了关于redis实现加锁的几种方法,加锁命令分别是INCR、SETNX和SET,文中给出了详细的示例代码,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧。
    2017-09-09
  • Redis中缓存预热与缓存穿透解决方案

    Redis中缓存预热与缓存穿透解决方案

    Redis缓存预热与缓存穿透是Redis缓存使用中的两个重要概念,文章首先介绍了Redis缓存预热和缓存穿透的基本概念,然后详细阐述了它们的产生原因和解决方案,感兴趣的可以了解一下
    2023-12-12
  • redis如何后台启动的方法

    redis如何后台启动的方法

    这篇文章主要介绍了redis如何后台启动的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-03-03
  • Redis中ziplist压缩列表的实现

    Redis中ziplist压缩列表的实现

    本文主要介绍了Redis中ziplist压缩列表的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-06-06

最新评论