这套API是ES官方提供的,用于java操作ES。maven项目直接导入依赖。
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>${elasticsearch.version}</version>
</dependency>
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>${elasticsearch.version}</version>
</dependency>
<properties>
<elasticsearch.version>7.6.0</elasticsearch.version>
</properties>
首先需要获得操作ES的客户端类RestHighLevelClient,Boot项目可以直接拿取。
@Autowired
private RestHighLevelClient restHighLevelClient;
//通过CreateIndexRequest创建索引请求
CreateIndexRequest request = new CreateIndexRequest("index01");
try{
//通过restHighLevelClient发起请求进行创建
CreateIndexResponse createIndexResponse = restHighLevelClient.indices().create(request, RequestOptions.DEFAULT);
}catch(Exception e){
log.info(e);
}
//通过DeleteIndexRequest创建删除请求
DeleteIndexRequest deleteIndexRequest = new DeleteIndexRequest("index01");
AcknowledgedResponse delete = restHighLevelClient.indices().delete(deleteIndexRequest, RequestOptions.DEFAULT);
GetIndexRequest request = new GetIndexRequest("index01");
boolean exists = restHighLevelClient.indices().exists(request, RequestOptions.DEFAULT);
//创建文档信息
IndexRequest request = new IndexRequest("index01");
//按需指定文档的id
request.id("01");
//指定超时时间
request.timeout("3s");
//设置请求刷新策略
request.setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE);
//存放数据,"goods"可以任意pojo类
request.source(JacksonUtil.bean2Json(goods), XContentType.JSON);
//发送请求
IndexResponse index = restHighLevelClient.index(request, RequestOptions.DEFAULT);
RefreshPolicy的刷新策略有以下三种:
RefreshPolicy.IMMEDIATE
RefreshPolicy.WAIT_UNTIL
RefreshPolicy.NONE
默认策略
请求向ElasticSearch提交了数据,不关系数据是否已经完成刷新,直接结束请求
优点:操作延时短、资源消耗低
缺点:实时性低
//创建修改请求,需要索引名与文档id
UpdateRequest request = new UpdateRequest("index01", "doc01");
//配置刷新策略
request.setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE);
request.timeout("3s");
//"goods"为文档对应的pojo类
request.doc(JacksonUtil.bean2Json(goods), XContentType.JSON);
UpdateResponse update = restHighLevelClient.update(request, RequestOptions.DEFAULT);
DeleteRequest request = new DeleteRequest("index01", id);
request.setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE);
request.timeout("3s");
DeleteResponse update = restHighLevelClient.delete(request, RequestOptions.DEFAULT);
ES的文档查询是整个教程的核心和重点,API提供了非常丰富的查询功能。
查询主要由以下几个类构成。
1.SearchRequest创建查询请求。
2.SearchSourceBuilder创建查询条件。
3.BoolQueryBuilder创建条件匹配。
4.HighlightBuilder创建字段高亮。
其中BoolQueryBuilder有两种过滤方式,分为must()和should(),作用可以理解为"and"和"or"。must()和should()方法的参数是QueryBuilders,QueryBuilders提供了许多的字段匹配方式。
matchQuery(“字段名”,“搜索词”)----->将搜索词分词,进行匹配,分的任意词匹配上都算。
termQuery(“字段名”,“搜索词”)----->搜索词不分词,搜什么查什么。
wildcardQuery(“字段名”,“搜索词”)----->搜索词可以使用通配符进行匹配。
以下是一次条件查询的演示。
public class SearchParam{
private Integer page;
private Integer size;
private String key;
private Integer type;
}
public void SearchDemo(SearchParam param){
//创建查询请求类
SearchRequest searchResult = new SearchRequest("index01");
//创建查询条件类
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//过滤查询的字段,参1是需要的字段数组,参2是剔除的字段数组
searchSourceBuilder.fetchSource(new String[]{"id", "description"},
new String[]{"time"});
//创建布尔查询条件类
BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
boolQueryBuilder.must(QueryBuilders.termQuery("type",param.getType()));
//搜索所有key字段中,存在顶象的内容
boolQueryBuilder.must(QueryBuilders.wildcardQuery("key","*顶象*"));
//创建高亮字段条件
HighlightBuilder highlightBuilder = new HighlightBuilder();
//指定高亮的字段
highlightBuilder.field("description");
//关闭多个字段高亮
highlightBuilder.requireFieldMatch(false);
//设置关键字前缀
highlightBuilder.preTags("");
//设置关键字后缀
highlightBuilder.postTags("");
//装配高亮条件
searchSourceBuilder.highlighter(highlightBuilder);
//装配查询条件
searchSourceBuilder.query(boolQueryBuilder);
//设置分页
searchSourceBuilder.from(param.getPage() * param.getSize());
searchSourceBuilder.size(param.getSize());
//设置超时时间
searchSourceBuilder.timeout(new TimeValue(30, TimeUnit.SECONDS));
//装配查询总条件
searchResult.source(searchSourceBuilder);
//发起查询请求获取结果
SearchResponse searchResponse = restHighLevelClient.search(searchResult, RequestOptions.DEFAULT);
//解析结果
ArrayList<Map<String, Object>> list = new ArrayList<>(param.getSize());
for (SearchHit hit : searchResponse.getHits().getHits()) {
//hit.getSourceAsMap()代表存入的一条记录
Map<String, Object> sourceAsMap = hit.getSourceAsMap();
//获取高亮字段
Map<String, HighlightField> highlightFields = hit.getHighlightFields();
HighlightField description = highlightFields.get("description");
//拼装高亮字段内容
if (description !=null){
Text[] fragments = description.getFragments();
StringBuilder new_des = new StringBuilder();
for (Text fragment : fragments) {
new_des.append(fragment);
}
//将拼装好的高亮字段重新设置
sourceAsMap.put("description",new_des);
}
//处理好的文档信息存入文档集合
list.add(sourceAsMap);
}
System.out.println(list);
}
高亮字段的原理是指定了description会查询高亮,例如"我热爱我的祖国"这一句话,如果搜索“热爱”关键字,那么会在搜索结果中保存“我”,“我的祖国”,以及“热爱 span>”三个字符串。将他们拼装起来存入原来的description,前端显示时解析,即可实现高亮。
同字段多值匹配条件
BoolQueryBuilder queryTemp = QueryBuilders.boolQuery();
list.forEach(name->queryTemp.should(QueryBuilders.termQuery("name",name)));
boolQueryBuilder.must(queryTemp);