# JRediSearch 独立客户端集成指南
## 📋 概述
JRediSearch 是 RediSearch 的官方 Java 客户端,提供了完整的全文搜索功能。本文档详细介绍如何在智柴图项目中集成和使用 JRediSearch 独立客户端。
## 🔧 环境准备
### 1. Redis 服务器配置
确保 Redis 服务器已安装并启用了 RediSearch 模块:
```bash
# 检查 RediSearch 是否已安装
redis-cli MODULE LIST | grep search
# 如果未安装,安装 RediSearch
# Docker 方式
docker run -p 6379:6379 redislabs/redisearch:latest
# 或编译安装
git clone https://github.com/RediSearch/RediSearch.git
cd RediSearch
make setup
make build
```
### 2. 项目依赖配置
在 `pom.xml` 中添加 JRediSearch 依赖:
```xml
com.redislabs
jredistimeseries
2.4.0
com.redislabs
jredisearch
2.4.0
redis.clients
jedis
4.3.1
```
## 🚀 基础集成
### 1. 配置类
```java
package com.zhichai.backend.config;
import io.redisearch.Client;
import io.redisearch.SearchResult;
import io.redisearch.Query;
import io.redisearch.Schema;
import io.redisearch.Document;
import io.redisearch.AggregationResult;
import io.redisearch.AggregationBuilder;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import java.util.HashMap;
import java.util.Map;
/**
* RediSearch 配置类
*/
@Configuration
public class RediSearchConfig {
@Value("${redis.host:localhost}")
private String redisHost;
@Value("${redis.port:6379}")
private int redisPort;
@Value("${redis.password:}")
private String redisPassword;
@Value("${redis.database:0}")
private int redisDatabase;
@Bean
public JedisPool jedisPool() {
JedisPoolConfig poolConfig = new JedisPoolConfig();
poolConfig.setMaxTotal(20);
poolConfig.setMaxIdle(10);
poolConfig.setMinIdle(5);
poolConfig.setTestOnBorrow(true);
if (redisPassword.isEmpty()) {
return new JedisPool(poolConfig, redisHost, redisPort, 2000, null, redisDatabase);
} else {
return new JedisPool(poolConfig, redisHost, redisPort, 2000, redisPassword, redisDatabase);
}
}
@Bean
public Client messageSearchClient(JedisPool jedisPool) {
// 创建消息搜索索引客户端
return new Client("message-index", jedisPool);
}
@Bean
public Client userSearchClient(JedisPool jedisPool) {
// 创建用户搜索索引客户端
return new Client("user-index", jedisPool);
}
}
```
### 2. 索引创建服务
```java
package com.zhichai.backend.service;
import io.redisearch.Client;
import io.redisearch.Schema;
import io.redisearch.Schema.TextField;
import io.redisearch.Schema.NumericField;
import io.redisearch.Schema.TagField;
import io.redisearch.IndexOptions;
import io.redisearch.Client.IndexOptions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import redis.clients.jedis.JedisPool;
import javax.annotation.PostConstruct;
import java.util.HashMap;
import java.util.Map;
/**
* RediSearch 索引管理服务
*/
@Service
public class RediSearchIndexService {
@Autowired
@Qualifier("messageSearchClient")
private Client messageSearchClient;
@Autowired
@Qualifier("userSearchClient")
private Client userSearchClient;
@Autowired
private JedisPool jedisPool;
/**
* 初始化搜索索引
*/
@PostConstruct
public void initializeIndexes() {
try {
createMessageIndex();
createUserIndex();
System.out.println("RediSearch 索引初始化完成");
} catch (Exception e) {
System.err.println("RediSearch 索引初始化失败: " + e.getMessage());
}
}
/**
* 创建消息搜索索引
*/
private void createMessageIndex() {
// 定义消息索引字段
Schema schema = new Schema()
.addTextField("content", 5.0) // 消息内容,权重5.0
.addTextField("authorName", 2.0) // 作者名称,权重2.0
.addNumericField("messageId") // 消息ID
.addNumericField("channelId") // 频道ID
.addNumericField("serverId") // 服务器ID
.addNumericField("authorId") // 作者ID
.addNumericField("createdAt") // 创建时间
.addTagField("messageType") // 消息类型标签
.addTagField("isPinned") // 是否置顶标签
.addTagField("isEdited") // 是否编辑标签
.addTagField("language"); // 语言标签
// 设置索引选项
IndexOptions options = IndexOptions.defaultOptions()
.setNoOffsets(false) // 保存偏移量
.setNoFields(false) // 保存字段
.setStopwords("") // 不使用停用词
.setLanguage("chinese"); // 设置为中文分词
try (var jedis = jedisPool.getResource()) {
// 检查索引是否已存在
boolean exists = jedis.exists("ft:message-index");
if (exists) {
// 删除旧索引
messageSearchClient.dropIndex();
}
// 创建新索引
messageSearchClient.createIndex(schema, options);
System.out.println("消息搜索索引创建成功");
}
}
/**
* 创建用户搜索索引
*/
private void createUserIndex() {
Schema schema = new Schema()
.addTextField("username", 5.0) // 用户名,权重5.0
.addTextField("nickname", 4.0) // 昵称,权重4.0
.addTextField("email", 2.0) // 邮箱,权重2.0
.addNumericField("userId") // 用户ID
.addNumericField("createdAt") // 创建时间
.addTagField("role") // 角色标签
.addTagField("isOnline") // 在线状态标签
.addTagField("language"); // 语言标签
IndexOptions options = IndexOptions.defaultOptions()
.setLanguage("chinese");
try (var jedis = jedisPool.getResource()) {
boolean exists = jedis.exists("ft:user-index");
if (exists) {
userSearchClient.dropIndex();
}
userSearchClient.createIndex(schema, options);
System.out.println("用户搜索索引创建成功");
}
}
}
```
## 🔍 搜索服务实现
### 1. 消息搜索服务
```java
package com.zhichai.backend.service;
import io.redisearch.Client;
import io.redisearch.Query;
import io.redisearch.SearchResult;
import io.redisearch.Document;
import io.redisearch.AggregationResult;
import io.redisearch.AggregationBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import com.zhichai.backend.model.MessageNode;
import java.util.*;
import java.util.stream.Collectors;
/**
* RediSearch 消息搜索服务
*/
@Service
public class RediSearchMessageService {
@Autowired
@Qualifier("messageSearchClient")
private Client messageSearchClient;
/**
* 基础文本搜索
*/
public List