ElasticSearch-SpringBoot集成
# ElasticSearch-SpringBoot集成
SpringBoot版本2.2.5
# 1. 官方文档 (opens new window)
- 第一步
- 第二步
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-client</artifactId>
<version>7.6.2</version>
</dependency>
1
2
3
4
5
2
3
4
5
配合版本
# 2. 创建SpringBoot项目
# 2.1 依赖
<!--elasticsearch依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
1
2
3
4
5
2
3
4
5
# 2.2. 问题
elasticsearch
版本问题: 版本与es
不一致
# 解决
<properties>
<!--自定义elasticsearch版本 7.6.1 -->
<elasticsearch.version>7.6.1</elasticsearch.version>
</properties>
1
2
3
4
2
3
4
注意: 导入依赖版本一定要与安装的es版本一致.
# 2.3 提供的对象
# spring data下的默认对象
# rest 对象
核心配置
/**
* Elasticsearch rest client infrastructure configurations.
*
* @author Brian Clozel
* @author Stephane Nicoll
*/
class RestClientConfigurations {
@Configuration(proxyBeanMethods = false)
static class RestClientBuilderConfiguration {
@Bean
@ConditionalOnMissingBean
RestClientBuilder elasticsearchRestClientBuilder(RestClientProperties properties,
ObjectProvider<RestClientBuilderCustomizer> builderCustomizers) {
HttpHost[] hosts = properties.getUris().stream().map(HttpHost::create).toArray(HttpHost[]::new);
RestClientBuilder builder = RestClient.builder(hosts);
PropertyMapper map = PropertyMapper.get();
map.from(properties::getUsername).whenHasText().to((username) -> {
CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
Credentials credentials = new UsernamePasswordCredentials(properties.getUsername(),
properties.getPassword());
credentialsProvider.setCredentials(AuthScope.ANY, credentials);
builder.setHttpClientConfigCallback(
(httpClientBuilder) -> httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider));
});
builder.setRequestConfigCallback((requestConfigBuilder) -> {
map.from(properties::getConnectionTimeout).whenNonNull().asInt(Duration::toMillis)
.to(requestConfigBuilder::setConnectTimeout);
map.from(properties::getReadTimeout).whenNonNull().asInt(Duration::toMillis)
.to(requestConfigBuilder::setSocketTimeout);
return requestConfigBuilder;
});
builderCustomizers.orderedStream().forEach((customizer) -> customizer.customize(builder));
return builder;
}
}
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(RestHighLevelClient.class)
static class RestHighLevelClientConfiguration {
// RestHighLevelClient 高级客户端,也是项目会用到的客户端
@Bean
@ConditionalOnMissingBean
RestHighLevelClient elasticsearchRestHighLevelClient(RestClientBuilder restClientBuilder) {
return new RestHighLevelClient(restClientBuilder);
}
@Bean
@ConditionalOnMissingBean
RestClient elasticsearchRestClient(RestClientBuilder builder,
ObjectProvider<RestHighLevelClient> restHighLevelClient) {
RestHighLevelClient client = restHighLevelClient.getIfUnique();
if (client != null) {
return client.getLowLevelClient();
}
return builder.build();
}
}
@Configuration(proxyBeanMethods = false)
static class RestClientFallbackConfiguration {
// RestHighLevelClient 普通客户端
@Bean
@ConditionalOnMissingBean
RestClient elasticsearchRestClient(RestClientBuilder builder) {
return builder.build();
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# 3 API使用
- 这里使用
rest对象
内容以JSON
格式展示
# 3.1 创建索引
class ElasticsearchApiApplicationTests {
/**
* @Autowired: 根据类型匹配
*/
@Autowired
@Qualifier("restHighLevelClient")
private RestHighLevelClient client;
/**
* 创建索引 Request CreateIndexRequest
*/
@Test
void contextLoads() throws IOException {
// 1. 创建索引请求
CreateIndexRequest request = new CreateIndexRequest("chggx_index");
// 2. 客户端执行请求
CreateIndexResponse createIndexResponse = client.indices().create(request, RequestOptions.DEFAULT);
// 3. 打印响应
System.out.println(createIndexResponse);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 3.2 获取索引
/**
* 获取索引 判断是否存在 GET GetIndexRequest
*/
@Test
void testExistIndex() throws IOException {
// 1. 获取索引请求
GetIndexRequest request = new GetIndexRequest("chggx_index");
// 2. 判断是否存在
boolean exists = client.indices().exists(request, RequestOptions.DEFAULT);
// 3. 打印结果 true
System.out.println(exists);
}
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
# 3.3 删除索引
/**
* 删除索引 DELETE DeleteIndexRequest
*/
@Test
void testDeleteIndex() throws IOException {
// 1. 获取删除请求
DeleteIndexRequest request = new DeleteIndexRequest("test2");
// 2. 删除索引
AcknowledgedResponse delete = client.indices().delete(request, RequestOptions.DEFAULT);
System.out.println(delete.isAcknowledged());
}
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
# 3.4 创建文档
/**
* 添加文档 IndexRequest
*/
@Test
void testAddDocument() throws IOException {
// 1. 创建对象
User user = new User("chggx", 12);
// 2. 创建请求
IndexRequest request = new IndexRequest("chggx_index");
// 3. 规则 /put/chggx_index/_doc/1
request.id("1");
// 超时 request.timeout("1s");
request.timeout(TimeValue.timeValueSeconds(1));
// 4. 将数据放入请求 JSON
request.source(JSON.toJSONString(user), XContentType.JSON);
// 5. 客户端发送请求,获取响应结果
IndexResponse indexResponse = client.index(request, RequestOptions.DEFAULT);
// IndexResponse[index=chggx_index,type=_doc,id=1,version=1,result=created,seqNo=0,primaryTerm=1,shards={"total":2,"successful":1,"failed":0}]
System.out.println(indexResponse.toString());
// CREATED 第一次创建: CREATED 以后更新 UPDATE
System.out.println(indexResponse.status());
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 3.5 获取文档
- 判断是否存在
/**
* 获取文档, 判断是否存在 GetRequest
*/
@Test
void testIsExists() throws IOException {
// 1. 创建获取请求
GetRequest getRequest = new GetRequest("chggx_index", "1");
// 2. 不获取返回的 _source 的上下文了
getRequest.fetchSourceContext(new FetchSourceContext(false));
// 3. 排序
getRequest.storedFields("_none_");
boolean exists = client.exists(getRequest, RequestOptions.DEFAULT);
System.out.println(exists);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
- 获取文档信息
/**
* 获取文档信息 GetRequest
*/
@Test
void testGetDocument() throws IOException {
// 1. 创建获取请求
GetRequest getRequest = new GetRequest("chggx_index", "1");
// 2. 获取文档信息
GetResponse getResponse = client.get(getRequest, RequestOptions.DEFAULT);
// 3. 打印文档内容 {"age":12,"name":"chggx"}
System.out.println(getResponse.getSourceAsString());
}
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
# 3.6 修改文档
/**
* 更新文档信息 UpdateRequest
*/
@Test
void testUpdateDocument() throws IOException {
// 1. 创建获取请求
UpdateRequest updateRequest = new UpdateRequest("chggx_index", "1");
// 2. 更新内容表
updateRequest.timeout("1s");
User user = new User("My CHGGX", 18);
// 转换为 Json 数据
updateRequest.doc(JSON.toJSONString(user), XContentType.JSON);
// 3. 获取文档信息 OK
UpdateResponse updateResponse = client.update(updateRequest, RequestOptions.DEFAULT);
// 4. 打印更新文档内容 OK
System.out.println(updateResponse.status());
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 3.7 删除文档
/**
* 删除文档信息
*/
@Test
void testDeleteDocument() throws IOException {
// 1. 创建获取请求
DeleteRequest deleteRequest = new DeleteRequest("test3", "1");
// 2 删除文档信息
DeleteResponse deleteResponse = client.delete(deleteRequest, RequestOptions.DEFAULT);
// 3. 打印文档内容 OK
System.out.println(deleteResponse.status());
}
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
# 3.8 批量添加
/**
* 特殊的,批量插入数据 BulkRequest
*/
@Test
void testBulkRequest() throws IOException {
// 1. 创建获取请求
BulkRequest bulkRequest = new BulkRequest();
// 2. 设置数据
bulkRequest.timeout("10s");
ArrayList<User> userList = new ArrayList<>();
userList.add(new User("Java 1", 5));
userList.add(new User("Java 2", 5));
userList.add(new User("Java 3", 5));
userList.add(new User("Java 4", 5));
userList.add(new User("Java 5", 5));
for (int i = 0; i < userList.size(); i++) {
// 批量添加
bulkRequest.add(
new IndexRequest("chggx_bulk")
.id("" + (i + 1))
.source(JSON.toJSONString(userList.get(i)), XContentType.JSON)
);
}
// 3. 批量添加
BulkResponse bulkResponse = client.bulk(bulkRequest, RequestOptions.DEFAULT);
// 4. 打印文档内容 OK
System.out.println(bulkResponse.status());
// 是否失败 false: 代表成功
System.out.println(bulkResponse.hasFailures());
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# 3.9 查询
/**
* 查询 SearchRequest
*/
@Test
void testSearch() throws IOException {
// 1. 创建获取请求
SearchRequest searchRequest = new SearchRequest("chggx_bulk");
// 2. 构建搜索条件
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
// QueryBuilders: 查询条件
// termQuery: 精确查询
// matchAllQuery: 匹配所有
TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("age", 5);
// MatchAllQueryBuilder matchAllQueryBuilder = QueryBuilders.matchAllQuery();
sourceBuilder.query(termQueryBuilder);
// 查询超时时间
sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
searchRequest.source(sourceBuilder);
// 3. 搜索信息
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
// 4. 打印文档内容 OK
System.out.println(JSON.toJSONString(searchResponse.getHits()));
System.out.println("============================================");
for (SearchHit documentFields : searchResponse.getHits().getHits()) {
System.out.println(documentFields.getSourceAsMap());
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
上次更新: 2023/04/11, 22:23:48