6 ElasticsearchRestTemplate
目录
6 ElasticsearchRestTemplate
6.1 概述
6.2 核心方法
6.3 SearchQuery 查询条件构建
示例 1:单条件匹配(文件名含 "test")
示例 2:多条件组合(布尔查询)
示例 3:高亮查询(文件名匹配 "test" 并高亮)
示例 4:排序 + 分页
示例 5:数组包含查询(tags 包含 "image")
6.4 SearchHits 返回值取值
6.5 注
6 ElasticsearchRestTemplate
6.1 概述
ElasticsearchRestTemplate 是 Spring Data Elasticsearch 中操作 ES 的 底层核心工具类(7.x 推荐替代旧版 ElasticsearchTemplate),与 ElasticsearchRepository 定位互补:
| 特性 | ElasticsearchRepository | ElasticsearchRestTemplate |
| 定位 | 高层封装(接口式) | 底层工具(模板化) |
| 使用方式 | 继承接口,调用约定方法(如 findById ) | 注入模板,手动构建查询(如 NativeSearchQueryBuilder ) |
| 适用场景 | 简单 CRUD、单条件查询 | 复杂查询(多条件、高亮、排序、聚合) |
| 灵活性 | 低(依赖方法命名约定 / 注解) | 高(支持原生 ES 查询语法) |
| 版本适配(7.8.0) | 支持,但复杂查询需自定义方法 | 完全支持,推荐复杂场景使用 |
6.2 核心方法
1.新增 / 更新:save() / saveAll()
- 作用:插入或更新文档(ID 存在则更新,不存在则新增)
- 示例:
// 单条保存
UserFileDocument doc = new UserFileDocument();
doc.setId("1"); // 文档ID(可选,不设则ES自动生成)
doc.setFileName("test.txt");
doc.setFileSize(1024);
esTemplate.save(doc); // 自动关联 @Document 注解的索引// 批量保存
List<UserFileDocument> docs = Arrays.asList(doc1, doc2);
esTemplate.saveAll(docs);
2.删除:deleteById() / deleteByQuery()
- 注意:7.8.0 中 无 delete(query, Class) 方法,按查询删除需用 deleteByQuery()
- 示例:
// 按 ID 删除
String docId = "1";
esTemplate.deleteById(docId, UserFileDocument.class);// 按查询条件删除(如删除文件名含 "temp" 的文档)
Query deleteQuery = new NativeSearchQueryBuilder().withQuery(QueryBuilders.matchQuery("fileName", "temp")) // 匹配条件.build();
esTemplate.deleteByQuery(deleteQuery, UserFileDocument.class); // 7.8.0 正确用法
3.单文档查询:get()
- 作用:按 ID 精确查询文档(返回单个实体)
- 示例:
String docId = "1";
UserFileDocument doc = esTemplate.get(docId, UserFileDocument.class);
System.out.println("文件名:" + doc.getFileName()); 4.复杂查询:search()(重点)
- 作用:执行复杂查询(多条件、高亮、排序、分页等)
- 参数:
- searchQuery:查询条件(由 NativeSearchQueryBuilder 构建,7.8.0 推荐)
- entityClass:返回结果对应的实体类(如 UserFileDocument.class)
- 返回值:SearchHits(包含匹配的文档、高亮、得分等元数据)
- 示例:见下
5.统计数量:count()
- 作用:按查询条件统计匹配的文档总数
- 示例:
// 统计文件大小大于 1024 的文档数
Query countQuery = new NativeSearchQueryBuilder().withQuery(QueryBuilders.rangeQuery("fileSize").gt(1024)).build();
long total = esTemplate.count(countQuery, UserFileDocument.class);
System.out.println("总数:" + total);
6.3 SearchQuery 查询条件构建
SearchQuery 是查询条件的封装,7.8.0 中主要通过 NativeSearchQueryBuilder 构建(支持原生 ES 查询语法),核心步骤:
- 创建 NativeSearchQueryBuilder 实例
- 链式调用方法添加条件(查询、过滤、高亮、排序、分页等)
- 调用 build() 生成 SearchQuery
常见查询条件示例(覆盖多场景)
假设 UserFileDocument 有字段:id(文档 ID)、fileName(文件名)、fileSize(文件大小)、uploadTime(上传时间)、tags(标签,数组)。
示例 1:单条件匹配(文件名含 "test")
SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(QueryBuilders.matchQuery("fileName", "test")) // 分词匹配.build();
示例 2:多条件组合(布尔查询)
需求:文件名含 "test" 且 文件大小 > 1024 且 上传时间在 2024-01-01 之后
SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(QueryBuilders.boolQuery().must(QueryBuilders.matchQuery("fileName", "test")) // 必须满足.filter(QueryBuilders.rangeQuery("fileSize").gt(1024)) // 过滤(不影响得分).filter(QueryBuilders.rangeQuery("uploadTime").gte("2024-01-01"))).build();
示例 3:高亮查询(文件名匹配 "test" 并高亮)
SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(QueryBuilders.matchQuery("fileName", "test")).withHighlightFields( // 配置高亮字段new HighlightBuilder.Field("fileName") // 高亮 "fileName" 字段.preTags("<em>") // 高亮前缀.postTags("</em>") // 高亮后缀).build();
示例 4:排序 + 分页
需求:按上传时间降序,取第 1 页(每页 10 条)
SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(QueryBuilders.matchAllQuery()) // 匹配所有.withSort(SortBuilders.fieldSort("uploadTime").order(SortOrder.DESC)) // 降序排序.withPageable(PageRequest.of(0, 10)) // 分页(页码从 0 开始).build();
示例 5:数组包含查询(tags 包含 "image")
SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(QueryBuilders.termsQuery("tags", "image")) // 精确匹配数组元素.build();
6.4 SearchHits 返回值取值
search() 方法返回 SearchHits,包含 匹配的文档列表、总条数、高亮信息、得分 等,核心取值方法:
| 方法 | 作用 | 返回类型 |
| getTotalHits() | 获取匹配的总文档数 | long |
| getSearchHits() | 获取所有匹配的文档(含元数据) | List> |
| getSearchHitById(String id) | 按 ID 获取单个匹配文档 | Optional> |
取值完整示例(结合高亮)
// 1. 构建查询条件(高亮 + 多条件)
SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(QueryBuilders.boolQuery().must(QueryBuilders.matchQuery("fileName", "test")).filter(QueryBuilders.rangeQuery("fileSize").gt(1024))).withHighlightFields(new HighlightBuilder.Field("fileName").preTags("<em>").postTags("</em>")).withPageable(PageRequest.of(0, 10)).build();// 2. 执行查询
SearchHits<UserFileDocument> searchHits = esTemplate.search(searchQuery, UserFileDocument.class);// 3. 取值
// 3.1 获取总条数
long total = searchHits.getTotalHits();
System.out.println("匹配总数:" + total);// 3.2 遍历匹配的文档(含高亮、得分)
List<SearchHit<UserFileDocument>> hits = searchHits.getSearchHits();
for (SearchHit<UserFileDocument> hit : hits) {// 获取文档实体(原始数据)UserFileDocument doc = hit.getContent();System.out.println("文档ID:" + doc.getId());System.out.println("原始文件名:" + doc.getFileName());// 获取高亮结果(若字段被高亮,优先用高亮值;否则用原始值)Map<String, List<String>> highlightFields = hit.getHighlightFields();String highlightedFileName = highlightFields.getOrDefault("fileName", Collections.singletonList(doc.getFileName())).get(0);System.out.println("高亮文件名:" + highlightedFileName);// 获取文档得分(相关性评分)float score = hit.getScore();System.out.println("相关性得分:" + score);// 获取文档元数据(如索引名、分片信息)String indexName = hit.getIndex();System.out.println("所属索引:" + indexName);
}
6.5 注
- NativeSearchQueryBuilder 是核心:7.x 推荐用它构建查询,替代旧版 SearchQueryBuilder
- 高亮字段必须在查询中配置:否则 getHighlightFields() 返回空
- 分页页码从 0 开始:PageRequest.of(0, 10) 表示第 1 页,每页 10 条
- deleteByQuery() 需注意权限:确保 ES 索引允许删除操作(无只读权限限制)
- 实体类注解:UserFileDocument 需加 @Document(indexName = "user_file") 指定索引名,字段需加 @Field 注解(如 @Field(type = FieldType.Text, analyzer = "ik_max_word"))
- elasticSearch和Spring Data Elasticsearch不同版本的方法差异较大,具体以官方文档为主。
