ElasticSearch——Spring Boot 集成 ES 操作详解
1、SpringBoot 集成 ES
1、新建一个Spring Boot 项目,添加 ElasticSearch 模块:
2、修改ES版本
可以看到,SpringBoot帮我们导入的ES版本是7.12.1:
而我们本地使用的版本是7.8.0,所以为了防止连接ES失败,要把版本号修改过成和本地一致。
<!-- 在pom.xml文件的properties属性下面添加: -->
<elasticsearch.version>7.8.0</elasticsearch.version>
一定要确保修改成功。
3、编写配置文件
package com.cheng;
import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.elasticsearch.client.RestClients;
@Configuration
public class ElasticSearchClientConfig {
//配置RestHighLevelClient依赖到spring容器中待用
@Bean
public RestHighLevelClient restHighLevelClient(){
RestHighLevelClient client = new RestHighLevelClient(
RestClient.builder(
//绑定本机,端口,协议,如果是ES集群,就配置多个
new HttpHost("127.0.0.1",9200,"http")));
return client;
}
}
到这里,ElasticSearch和SpringBoot的集成就完成了,下面就是关于索引和文档API的使用。
Java REST Client
Java REST Client 有两种风格:
- Java Low Level REST Client :用于Elasticsearch的官方低级客户端。它允许通过http与Elasticsearch集群通信。将请求编排和响应反编排留给用户自己处理。它兼容所有的Elasticsearch版本。
- Java High Level REST Client :用于Elasticsearch的官方高级客户端。它是基于低级客户端的,它提供很多API,并负责请求的编排与响应的反编排。
- 官方更建议我们用Java High Level REST Client,它执行HTTP请求,而不是序列号的Java请求。
下面测试使用的是 Java 高级客户端。
2、索引的API操作详解
创建索引
//创建索引测试
@Test
void contextLoads() throws IOException {
//创建索引的请求
CreateIndexRequest request = new CreateIndexRequest("wanli");
//执行创建索引的请求,返回一个响应
CreateIndexResponse response = client.indices().create(request, RequestOptions.DEFAULT);
//打印响应
System.out.println(response); //org.elasticsearch.client.indices.CreateIndexResponse@6ce3e00
}
RestHighLevelClient中的所有API都接受RequestOptions,您可以使用该选项定制请求,而不会改变Elasticsearch执行请求的方式。例如,您可以在此处指定一个节点选择器来控制哪个节点接收请求。
判断索引是否存在
//判断索引是否存在,存在返回true,不存在返回false
@Test
public void test1() throws IOException {
GetIndexRequest request = new GetIndexRequest("wanli_index");
boolean b = client.indices().exists(request, RequestOptions.DEFAULT);
System.out.println(b); //true
}
删除索引
//删除索引
@Test
public void test2() throws IOException {
DeleteIndexRequest request = new DeleteIndexRequest("wanli_index");
AcknowledgedResponse response = client.indices().delete(request,RequestOptions.DEFAULT);
System.out.println(response.isAcknowledged()); //返回true删除成功
}
3、文档的API操作详解
添加文档
实体类:
@Component
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private String name;
private int age;
}
添加文档代码:
@Test
public void test3() throws IOException {
User user = new User("万里", 3);
//创建请求
IndexRequest request = new IndexRequest("wanli_index");
request
.id("1") //文档id,不指定会有默认id
.timeout(TimeValue.timeValueSeconds(1))//分片超时时间
.source(JSON.toJSONString(user), XContentType.JSON); //将文档源设置为索引,user对象转化成json字符串
IndexResponse response = client.index(request, RequestOptions.DEFAULT);
System.out.println(response.toString()); //IndexResponse[index=wanli_index,type=_doc,id=1,version=1,result=created,seqNo=0,primaryTerm=1,shards={"total":2,"successful":1,"failed":0}]
System.out.println(response.status());//CREATED 操作状态
}
判断文档是否存在
//判断文档是否存在
@Test
public void test4() throws IOException {
//针对指定的索引和文档 ID 构造一个新的 get 请求
GetRequest request = new GetRequest("wanli_index","1");
String[] includes = Strings.EMPTY_ARRAY;
String[] excludes = new String[]{"age"};//值获取 _source 中包含age的文档信息
//fetchSourceContext指定需要返回字段的上下文,提供更加完善的过滤逻辑,主要特性为支持include、exclude和支持通篇符过滤。
request.fetchSourceContext(new FetchSourceContext(true, includes, excludes));
boolean b = client.exists(request, RequestOptions.DEFAULT);
System.out.println(b); //true则存在
}
获取文档信息
//获取文档信息
@Test
public void test5() throws IOException {
GetRequest request = new GetRequest("wanli_index", "1");
GetResponse response = client.get(request, RequestOptions.DEFAULT);
System.out.println(response.toString());//{"_index":"wanli_index","_type":"_doc","_id":"1","_version":1,"_seq_no":0,"_primary_term":1,"found":true,"_source":{"age":3,"name":"万里"}}
System.out.println(response.getSource());//获取_source:{name=万里, age=3}
System.out.println(response.getVersion());//1
System.out.println(response);//{"_index":"wanli_index","_type":"_doc","_id":"1","_version":1,"_seq_no":0,"_primary_term":1,"found":true,"_source":{"age":3,"name":"万里"}}
}
修改文档信息
//修改文档信息
@Test
public void test6() throws IOException {
UpdateRequest request = new UpdateRequest("wanli_index", "1");
request.timeout("1s");
User user = new User("神明", 18);
//doc里面填具体的内容和文档格式
request.doc(JSON.toJSONString(user),XContentType.JSON);
UpdateResponse response = client.update(request, RequestOptions.DEFAULT);
System.out.println(response.status()); //返回ok表示操作成功
}
删除文档
//删除文档
@Test
public void test7() throws IOException {
DeleteRequest request = new DeleteRequest("wanli_index", "1");
request.timeout("1s");
DeleteResponse response = client.delete(request, RequestOptions.DEFAULT);
System.out.println(response.status());//返回ok表示操作成功
}
批量插入文档
BulkRequest:批量请求包含有序的IndexRequest 、 DeleteRequest 和UpdateRequest ,并允许在单个批处理中执行它。 请注意,我们仅支持批量请求而不是每个项目的刷新。
//批量插入文档
@Test
public void test8() throws IOException {
BulkRequest request = new BulkRequest();
request.timeout("10s");
ArrayList<User> list = new ArrayList<>();
list.add(new User("shenming1",3));
list.add(new User("shenming2",3));
list.add(new User("shenming3",3));
list.add(new User("shenming4",3));
list.add(new User("shenming5",3));
for (int i = 0; i < list.size(); i++) {
request.add(
new IndexRequest("wanli_index")
.id(""+(i+1))
.source(JSON.toJSONString(list.get(i)),XContentType.JSON));
}
BulkResponse response = client.bulk(request, RequestOptions.DEFAULT);
System.out.println(response.status()); //ok
}
根据具体的需求调用下面的方法。
复杂查询操作
1、构建查询请求:SearchRequest request = new SearchRequest(“wanli_index”);
2、构建搜索条件:SearchSourceBuilder sourceBuilder = SearchSourceBuilder.searchSource();
3、将查询条件放入请求:request.source(sourceBuilder);
4、执行请求:SearchResponse response = client.search(request, RequestOptions.DEFAULT);
@Test
public void test9() throws IOException {
//构建查询请求
SearchRequest request = new SearchRequest("wanli_index");
//构建搜索条件
SearchSourceBuilder sourceBuilder = SearchSourceBuilder.searchSource();
//设置高亮
//HighlightBuilder highlightBuilder = new HighlightBuilder();
//highlightBuilder.field("name");
//highlightBuilder.preTags("<span style='color:red'>");
//highlightBuilder.postTags("</span>");
//searchSourceBuilder.highlighter(highlightBuilder);
//分页:
//sourceBuilder.from(0);
//sourceBuilder.size(10);
//QueryBuilders 工具类实现查询条件的构建
//QueryBuilders.termQuery 精确查询
//QueryBuilders.matchAllQuery() 匹配所有
TermQueryBuilder queryBuilder = QueryBuilders.termQuery("name", "shenming1");
sourceBuilder.query(queryBuilder);//将精确查询条件放入搜索条件
sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));//设置超时时间
//将查询条件放入请求
request.source(sourceBuilder);
//执行请求
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
//打印搜索命中文档结果
System.out.println(JSON.toJSONString(response.getHits()));
//{"fragment":true,"hits":[{"fields":{},"fragment":false,"highlightFields":{},"id":"1","matchedQueries":[],"primaryTerm":0,"rawSortValues":[],"score":1.1727202,"seqNo":-2,"sortValues":[],"sourceAsMap":{"name":"shenming1","age":3},"sourceAsString":"{\"age\":3,\"name\":\"shenming1\"}","sourceRef":{"fragment":true},"type":"_doc","version":-1}],"maxScore":1.1727202,"totalHits":{"relation":"EQUAL_TO","value":1}}
System.out.println("====================================");
for (SearchHit searchHit : response.getHits().getHits()) {
System.out.println(searchHit.getSourceAsMap());//{name=shenming1, age=3}
}
}