一、依赖
<!-- Spring Boot 3.x/2.x 通用 -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
二、注入点 名称 来源 场景 ElasticsearchRestTemplate
自动配置 通用模板,拼 DSL、聚合、高亮 ElasticsearchRepository<T,ID>
自己继承 方法名即查询,最简单 CRUD
代码示例:
@Service
public class EsDemoService {/* ① 模板方式:拼 NativeQuery、聚合、高亮 */@Resourceprivate ElasticsearchRestTemplate template;/* ② Repository 方式:方法名即查询 */@Resourceprivate DocRepository repository;
}
三、ElasticsearchRestTemplate 常用函数 分类 方法 说明 索引操作 boolean indexExists(String indexName)
判断索引是否存在 boolean createIndex(String indexName)
创建索引 boolean deleteIndex(String indexName)
删除索引 文档操作 T save(T entity)
新增/更新(ID 存在即覆盖) T get(String id, Class<T> clazz)
主键查询 boolean delete(String id, Class<T> clazz)
主键删除 List<T> saveAll(Collection<T> entities)
批量插入/更新 查询 SearchHits<T> search(Query query, Class<T> clazz)
通用查询,返回 SearchHits List<T> searchForList(Query query, Class<T> clazz)
直接 List 聚合 SearchHits<T> search(Query query, Class<T> clazz)
query 里携带 Aggregation 高亮 同上,query 里 .withHighlightBuilder(...)
高亮结果在 SearchHit#getHighlightFields()
四、快速代码片段
// 1. 是否存在
boolean ok = template.indexExists("product");// 2. 插入/更新
Product p = new Product(1L, "iPhone 15", "手机", 7999.0, "");
Product saved = template.save(p);// 3. 主键查询
Product one = template.get("1", Product.class);// 4. 条件+分页+排序
BoolQueryBuilder bq = QueryBuilders.boolQuery().must(QueryBuilders.matchQuery("title", "iPhone")).filter(QueryBuilders.rangeQuery("price").gte(5000));
NativeQuery query = NativeQuery.builder().withQuery(bq).withPageable(PageRequest.of(0, 5, Sort.by(Sort.Order.desc("price")))).build();
SearchHits<Product> hits = template.search(query, Product.class);
List<Product> list = hits.stream().map(SearchHit::getContent).toList();// 5. 聚合:平均价格
NativeQuery aggQuery = NativeQuery.builder().withAggregation("avg_price", AggregationBuilders.avg("avgPrice").field("price")).build();
SearchHits<Product> aggHits = template.search(aggQuery, Product.class);
double avg = ((ParsedAvg) aggHits.getAggregations().get("avgPrice")).getValue();
五、与 RedisTemplate 对照记忆 Redis Elasticsearch RedisTemplate<String,Object>
ElasticsearchRestTemplate
opsForValue()
/ opsForHash()
save()
/ search()
/ delete()
序列化由 RedisSerializer
处理 序列化由 ElasticsearchConverter
自动完成(默认 Jackson)
六、自定义序列化器
package com.example.esdemo.config;import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter;
import org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter;
import org.springframework.data.elasticsearch.core.mapping.SimpleElasticsearchMappingContext;@Configuration
public class EsConverterConfig {/*** 覆盖默认 ElasticsearchConverter,使用定制 ObjectMapper*/@Beanpublic ElasticsearchConverter elasticsearchConverter() {ObjectMapper mapper = new ObjectMapper();mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);mapper.registerModule(new JavaTimeModule()); // 支持 LocalDateTimeMappingElasticsearchConverter converter =new MappingElasticsearchConverter(new SimpleElasticsearchMappingContext());converter.setObjectMapper(mapper);return converter;}
}
七 、结论
只要引入 spring-boot-starter-data-elasticsearch
,直接注入 ElasticsearchRestTemplate
,就能像 RedisTemplate
一样开箱即用,所有 CRUD、聚合、高亮、分页函数 模板里已经自带,无需额外封装。