










Elasticsearch 是一个基于 Apache Lucene 构建的分布式、RESTful 风格的搜索和数据分析引擎。它通常被用来替代传统数据库(如 MySQL)在模糊查询、全文检索、多维度筛选等场景下的不足。
为了方便理解,我们可以将其与 MySQL 进行类比:
| Elasticsearch | 关系型数据库 | 说明 |
|---|---|---|
| Index (索引) | Database (数据库) | ES 7.x 之后,Index 更像一张表,但在逻辑上相当于数据库。 |
| Type (类型) | Table (表) | ES 7.x 之后已弱化,一个 Index 只对应一个 Type,通常不再提及。 |
| Document (文档) | Row (行/记录) | ES 存储数据的单元,通常是 JSON 格式。 |
| Field (字段) | Column (列) | 文档中的属性。 |
| Mapping (映射) | Schema (表结构) | 定义字段名称、类型(text, keyword, integer等)等约束。 |
| DSL (查询语言) | SQL | ES 使用 JSON 格式的 DSL 进行查询。 |
在 Spring Boot 项目中,主要有两种主流的使用方式:
确保本地或服务器已安装 Elasticsearch(建议版本 7.x 或 8.x)。
在 pom.xml 中添加依赖(版本需与安装的 ES 版本对应):
<!-- Spring Boot Starter Data Elasticsearch -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
<!-- Lombok (用于简化代码) -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
在 application.yml 中配置 ES 的地址和端口:
spring:
elasticsearch:
uris: http://localhost:9200 # ES 地址
# username: elastic # 如果开启了安全认证
# password: your_password
使用 @Document 注解映射索引,@Field 注解定义字段属性。
import lombok.Data;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;
@Data
@Document(indexName = "product_index") // 索引名称,类似于表名
public class Product {
@Id
private Long id; // 主键
@Field(type = FieldType.Text, analyzer = "ik_max_word") // 文本类型,指定分词器
private String name;
@Field(type = FieldType.Keyword) // 关键字类型,不分词,精确匹配
private String category;
@Field(type = FieldType.Double)
private Double price;
@Field(type = FieldType.Text)
private String description;
}
继承 ElasticsearchRepository,即可获得基本的 CRUD 和简单查询能力。
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface ProductRepository extends ElasticsearchRepository<Product, Long> {
// 方法命名规则查询 (自动实现)
// 查询指定分类下的商品
List<Product> findByCategory(String category);
// 价格范围查询
List<Product> findByPriceBetween(Double min, Double max);
}
基本 CRUD 操作:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Optional;
@Service
public class ProductService {
@Autowired
private ProductRepository productRepository;
// 1. 新增/修改文档
public void saveProduct() {
Product product = new Product();
product.setId(1L);
product.setName("苹果手机 iPhone 15");
product.setCategory("手机");
product.setPrice(6999.00);
productRepository.save(product); // 自动生成索引和文档
}
// 2. 查询单个
public Product getProduct(Long id) {
Optional<Product> product = productRepository.findById(id);
return product.orElse(null);
}
// 3. 简单条件查询
public List<Product> getByCategory() {
return productRepository.findByCategory("手机");
}
}
复杂查询:
对于复杂的业务查询(如组合条件、高亮显示、分页排序),我们需要使用 ElasticsearchRestTemplate 或 Criteria API。
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.query.Criteria;
import org.springframework.data.elasticsearch.core.query.CriteriaQuery;
import org.springframework.data.elasticsearch.core.query.Query;
import java.util.List;
import java.util.stream.Collectors;
@Service
public class ProductSearchService {
@Autowired
private ElasticsearchRestTemplate elasticsearchTemplate;
// 复杂查询示例:搜索名字包含关键词且价格在范围内的商品
public List<Product> searchProducts(String keyword, Double minPrice, Double maxPrice) {
// 1. 构建查询条件
Criteria criteria = Criteria.where("name").contains(keyword)
.and("price").between(minPrice, maxPrice);
// 2. 构建查询对象
Query query = new CriteriaQuery(criteria);
// 3. 执行查询
SearchHits<Product> searchHits = elasticsearchTemplate.search(query, Product.class);
// 4. 转换结果
return searchHits.stream()
.map(SearchHit::getContent)
.collect(Collectors.toList());
}
}
如果 Spring Data 的封装无法满足需求,你可以使用 NativeQuery 直接构建 ES 的 DSL JSON 查询:
import org.springframework.data.elasticsearch.core.query.NativeQuery;
import org.elasticsearch.index.query.QueryBuilders; // 注意导入包
public List<Product> nativeSearch(String name) {
// 使用 QueryBuilders 构建原生 Elasticsearch 查询条件
NativeQuery query = NativeQuery.builder()
.withQuery(QueryBuilders.matchQuery("name", name))
.withPageable(PageRequest.of(0, 10)) // 分页
.build();
SearchHits<Product> hits = elasticsearchTemplate.search(query, Product.class);
return hits.stream().map(SearchHit::getContent).collect(Collectors.toList());
}
@Document 映射索引。ElasticsearchRepository 实现快速 CRUD。ElasticsearchRestTemplate 处理复杂查询。此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。