SpringBoot集成RedisSearch
文章目录
- 1.背景
- 2.安装redisSearch
- 3.添加Maven依赖
- 4.配置类
- 5.实体类和索引
- 5.1 定义实体类
- 5.2 创建索引(含地理字段)
- 6.数据操作服务
- 7.搜索功能实现
- 7.1 基础搜索
- 7.2 高级搜索功能
- 8.测试
1.背景
Redis Search 是 Redis 官方提供的全文搜索引擎,它为Redis 提供全文搜索、索引和复杂查询功能。它基于内存存储,结合了 Redis 的高性能和倒排索引技术,支持实时搜索、聚合分析、模糊匹配等场景。RedisSearch 适用于需要快速检索结构化或非结构化数据的应用,如电商搜索、日志分析、实时推荐等。更多详细的介绍可参见:《一文了解亿级数据检索:RedisSearch》
2.安装redisSearch
本文不在赘述,详情可参见:《docker安装redisSearch》
3.添加Maven依赖
<dependencies>
<!-- SpringBoot Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- RedisSearch 核心依赖 -->
<dependency>
<groupId>com.redislabs</groupId>
<artifactId>jredisearch</artifactId>
<version>2.2.0</version>
<exclusions>
<exclusion>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- 适配 Redis 7.x 的 Jedis -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
</dependencies>
4.配置类
import io.redisearch.client.Client;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class RedisSearchConfig {
@Value("${spring.redis.host}")
private String host;
@Value("${spring.redis.port}")
private int port;
@Bean
public Client redisSearchClient() {
// 创建 RediSearch 客户端
return new Client("productIndex", host, port);
}
}
application.properties
spring.redis.host=127.0.0.1
spring.redis.port=6379
5.实体类和索引
5.1 定义实体类
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import redis.clients.jedis.GeoCoordinate;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Product {
private String id;
private String title;
private Double price;
private String category;
private GeoCoordinate location; // 地理位置坐标
}
5.2 创建索引(含地理字段)
import io.redisearch.Schema;
import io.redisearch.client.Client;
import io.redisearch.client.IndexDefinition;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class IndexService {
@Autowired
private Client client;
public void createProductIndex() {
Schema schema = new Schema()
.addTextField("title", 5.0) // 文本字段,权重5.0
.addNumericField("price") // 数值字段
.addTagField("category") // 标签字段
.addGeoField("location"); // 地理字段
IndexDefinition rule = new IndexDefinition(IndexDefinition.Type.HASH)
.setPrefixes("product:"); // 自动索引以 product: 开头的键
client.createIndex(schema, Client.IndexOptions.defaultOptions().setDefinition(rule));
}
}
6.数据操作服务
import com.example.mapstuct.dto.Product;
import io.redisearch.Document;
import io.redisearch.client.Client;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Map;
@Service
public class ProductService {
@Autowired
private Client client;
// 添加文档
public void addProduct(Product product) {
Document doc = new Document("product:" + product.getId())
.set("title", product.getTitle())
.set("price", product.getPrice())
.set("category", product.getCategory())
.set("location", product.getLocation().getLongitude() + "," + product.getLocation().getLatitude());
client.addDocument(doc);
}
// 更新文档
public void updateProduct(String id, Double score, Map<String, Object> fields) {
client.updateDocument("product:" + id, score, fields);
}
// 删除文档
public void deleteProduct(String id) {
client.deleteDocument("product:" + id);
}
public SearchResult searchProducts(String query) {
return client.search(
new Query(query)
.limit(0, 10) // 分页
.setWithScores() // 返回相关性评分
);
}
public SearchResult searchProductsByQuery(Query query) {
return client.search(query);
}
}
7.搜索功能实现
7.1 基础搜索
public SearchResult searchProducts(String query) {
return client.search(
new Query(query)
.limit(0, 10) // 分页
.setWithScores() // 返回相关性评分
);
}
7.2 高级搜索功能
// 高亮显示
Query query = new Query("蓝牙耳机")
.highlight("title", "<b>", "</b>"); // 高亮标题字段中的匹配词[1](@ref)
// 通配符搜索
Query wildcardQuery = new Query("蓝*"); // 匹配“蓝牙”“蓝色”等[1](@ref)
// 布尔逻辑
Query boolQuery = new Query("耳机 AND -入耳式"); // 包含“耳机”且不包含“入耳式”[1](@ref)
// 范围查询
Query rangeQuery = new Query("@price:[200 500]"); // 价格区间过滤[1](@ref)
// 地理位置检索(100公里内)
Query geoQuery = new Query("@location:[经度 纬度 100 km]"); // 基于坐标的范围查询[23,24](@ref)
8.测试
@SpringBootTest
public class RedisSearchDemoTest {
@Autowired
private IndexService indexService;
@Autowired
private ProductService productService;
@Test
void fullDemoTest() {
// 1. 创建索引
indexService.createProductIndex();
// 2. 添加数据
Product p1 = new Product("1", "无线蓝牙耳机", 299.0,
"电子产品", new GeoCoordinate(116.397469, 39.908821));
productService.addProduct(p1);
// 3. 执行高级搜索
SearchResult result = productService.searchProducts(
"@category:{电子产品} @price:[200 300] @location:[116.397469 39.908821 10 km]"
);
// 4. 输出高亮结果
result.getDocuments().forEach(doc ->
System.out.println("高亮标题:" + doc.get("title")));
}
}