最近做一个项目需要从大量的数据中全文搜索,一开始想用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创建添加的模型的索引,导致报错
添加映射模型
这里以一个简单的文章实体类为例
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要清除一下缓存,然后新编写的才能生效
仓库地址
正文完