Springboot使用redis-om-spring操作redisSearch

42次阅读
没有评论

最近做一个项目需要从大量的数据中全文搜索,一开始想用Elastic Search,但是太复杂了,然后就找到了Redis Search,但是网上找不到几个关于redis-om-spring这个框架和Redis Search一起使用的文章,便记录一下

使用docker安装并启动redis-stack

docker run -p 6379:6379 -p 8001:8001 redis/redis-stack

安装了redis-stack启动了之后,本地的redis就没有必要启动了,启动了 Redis Stack 后,Redis Stack 包含了标准的 Redis 服务器以及附加的模块,例如 RedisJSON、RedisSearch、RedisGraph 等。因此,当你启动 Redis Stack 时,标准的 Redis 服务器已经作为其中的一部分运行了。

配置springboot application.yaml的redis部分

spring:
  data:
    redis:
      host: your.cloud.db.redislabs.com
      port: 12345
      password: xxxxxxxx
      username: default

在springboot启动类添加扫描注解

添加@EnableRedisDocumentRepositories

这里没添加的话,可能不会在redis创建添加的模型的索引,导致报错

Springboot使用redis-om-spring操作redisSearch

添加映射模型

这里以一个简单的文章实体类为例

package com.ham.jujihe_backend.domain.redisEntity;

import com.redis.om.spring.annotations.Document;
import com.redis.om.spring.annotations.Indexed;
import com.redis.om.spring.annotations.Searchable;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.data.annotation.Id;

import java.time.LocalDateTime;

/**
 * @description: redis文章实体类
 * @author: ham
 * @date: 2024/10/19 15:07
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
@Document
public class RedisPost {
    @Id
    private String id; // 文章主键
    @Searchable
    private String title; // 文章标题
    @Searchable
    private String content; // 文章内容
    private String author; // 文章作者
    @Indexed
    private LocalDateTime publishTime; // 发布时间
}

其中,@Id 注解用于标识实体类中的主键字段,没有赋值的话,它可以自动生成。@Indexed 注解用于为字段创建索引。@Searchable 注解允许对字段进行全文检索(full-text search)。它不仅支持精确匹配,还支持模糊匹配或部分内容搜索。这对于处理大量文本数据(如文章内容或评论)非常有用。

添加持久层

package com.ham.jujihe_backend.repository;

import com.ham.jujihe_backend.domain.redisEntity.RedisPost;
import com.redis.om.spring.repository.RedisDocumentRepository;

/**
 * @description: RedisPost持久层
 * @author: ham
 * @date: 2024/10/19 13:59
 */
public interface RedisPostRepository extends RedisDocumentRepository<RedisPost, String> {

}

工具类

我封装了一个简单的工具类,以便实现简单的分页

package com.ham.jujihe_backend.utils;

import com.ham.jujihe_backend.domain.redisEntity.RedisPost;
import com.ham.jujihe_backend.domain.redisEntity.RedisPost$;
import com.redis.om.spring.search.stream.EntityStream;
import com.redis.om.spring.search.stream.SearchStream;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Component;
import redis.clients.jedis.search.aggr.SortedField;

import java.util.List;
import java.util.stream.Collectors;

/**
 * @description: RedisSearch工具类
 * @author: ham
 * @date: 2024/10/19 15:42
 */
@Component
public class RedisSearchUtil {
    @Resource
    private EntityStream entityStream;

    /**
     * @param keyword:     关键词 (为空则查询全部文章)
     * @param pageNum:     页码
     * @param pageSize:    每页记录数
     * @return java.util.List<com.ham.jujihe_backend.domain.redisEntity.RedisPost>
     * @description: 根据条件搜索 RedisPost
     * @author: ham
     * @date: 2024/10/19 15:24
     **/
    public List<RedisPost> searchPost(String keyword, int pageNum, int pageSize) {
        int skip = (pageNum - 1) * pageSize; // 计算跳过的记录数

        // 创建基本的查询流
        SearchStream<RedisPost> searchStream = entityStream.of(RedisPost.class)
                .filter(RedisPost$.TITLE.containing(keyword)
                        .or(RedisPost$.CONTENT.containing(keyword))
                        ));

        return searchStream.skip(skip) // 跳过指定数量的记录
                .limit(pageSize) // 设置每页的大小
                .sorted(RedisPost$.PUBLISH_TIME, SortedField.SortOrder.DESC)
                .collect(Collectors.toList());
    }

}

注意,如果这里面用到的查询条件的字段都要使用注解注册成为索引,不然会报错

提示

每次修改了实体类之后,要在redis把之前的索引删掉,然后maven要清除一下缓存,然后新编写的才能生效

仓库地址

redis-om-spring

正文完
 0
评论(没有评论)
验证码