java整合ElasticSearch上
Salted Fish 2024/7/12 语法
# 一、ES概述
ES是一个使用Java语言并且基于Lucene编写的搜索引擎框架,他提供了分布式的全文搜索功能,提供了一个统一的基于RESTful风格的WEB接口,官方客户端也对多种语言都提供了相应的API。
Lucene:Lucene本身就是一个搜索引擎的底层。
分布式:ES主要是为了突出他的横向扩展能力。
全文检索:将一段词语进行分词,并且将分出的单个词语统一的放到一个分词库中,在搜索时,根据关键字去分词库中检索,找到匹配的内容。(倒排索引)
RESTful风格的WEB接口:操作ES很简单,只需要发送一个HTTP请求,并且根据请求方式的不同,携带参数的同,执行相应的功能。
应用广泛:Github.com,WIKI,Gold Man用ES每天维护将近10TB的数据。
# 二、Java操作ElasticSearch
# 2.1 导入依赖
<!-- ElasticSearch -->
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>${elasticsearch.version}</version>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-client</artifactId>
<version>${elasticsearch.version}</version>
</dependency>
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>${elasticsearch.version}</version>
</dependency>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 2.2 连接工具类
import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.Arrays;
@Configuration
public class ElasticSearchConfig {
// 连接超时时间
@Value("${elasticsearch.connectTimeOut}")
private int connectTimeOut;
// 连接超时时间
@Value("${elasticsearch.socketTimeOut}")
private int socketTimeOut;
// 获取连接的超时时间
@Value("${elasticsearch.connectionRequestTimeOut}")
private int connectionRequestTimeOut;
// 最大连接数
@Value("${elasticsearch.maxConnTotal}")
private int maxConnTotal;
// 最大路由连接数
@Value("${elasticsearch.maxConnPerRoute}")
private int maxConnPerRoute;
// 使用协议
@Value("${elasticsearch.scheme:http}")
private String scheme;
// 服务节点
@Value("${elasticsearch.nodes}")
private String[] nodes;
// 鉴权账号
@Value("${elasticsearch.username}")
private String username;
// 账号密码
@Value("${elasticsearch.password}")
private String password;
@Bean(name = "restHighLevelClient")
public RestHighLevelClient restHighLevelClient() {
final CredentialsProvider credentialsProvider =
new BasicCredentialsProvider();
credentialsProvider.setCredentials(AuthScope.ANY,
new UsernamePasswordCredentials(username, password));
RestClientBuilder builder = RestClient.builder(hosts())
.setHttpClientConfigCallback(httpClientBuilder -> {
httpClientBuilder.setMaxConnTotal(maxConnTotal)
.setMaxConnPerRoute(maxConnPerRoute)
.setDefaultCredentialsProvider(credentialsProvider);
return httpClientBuilder;
})
.setRequestConfigCallback(requestConfigBuilder -> {
requestConfigBuilder.setConnectTimeout(connectTimeOut)
.setSocketTimeout(socketTimeOut)
.setConnectionRequestTimeout(connectionRequestTimeOut);
return requestConfigBuilder;
});
return new RestHighLevelClient(builder);
}
private HttpHost[] hosts() {
return Arrays.asList(nodes).stream().map(node -> {
String[] array = node.split(":");
return new HttpHost(array[0], Integer.parseInt(array[1]), scheme);
}).toArray(HttpHost[]::new);
}
}
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
75
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
75
# 2.3 Java操作索引
/**
* es实体类
*/
public class Person {
//json转换的时候忽略这个id
@JsonIgnore
private String id;
//姓名
private String name;
//年龄
private Integer age;
//出生日期, 日期格式必须和ES中这个索引字段的日期格式保持一致
@JsonFormat(pattern = "yyyy-MM-dd")
private Date birthday;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 2.3.1 创建索引
import com.tingyi.utils.EsClient;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.CreateIndexResponse;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.json.JsonXContent;
import org.junit.Test;
public class TestIndexManage {
//es连接
@Autowired
private RestHighLevelClient restHighLevelClient;
//索引库名字
private String index = "person";
/**
* 创建分片, 索引以及索引结构
* @throws Exception
*/
@Test
public void testCreateIndex() throws Exception {
//1. 创建主分片和备份分片
Settings.Builder settings = Settings.builder()
.put("number_of_shards", 5)
.put("number_of_replicas", 1);
//2. 创建索引结构
XContentBuilder mapping = JsonXContent.contentBuilder()
.startObject()
.startObject("properties")
.startObject("name")
.field("type", "text")
.endObject()
.startObject("age")
.field("type", "integer")
.endObject()
.startObject("birthday")
.field("type", "date")
.field("format", "yyyy-MM-dd")
.endObject()
.endObject()
.endObject();
//3. 将分片和索引结构封装成一个Request对象
CreateIndexRequest request = new CreateIndexRequest(index)
.settings(settings)
.mapping(mapping);
//4. 发送请求执行创建并返回响应
CreateIndexResponse response = restHighLevelClient.indices().create(request, RequestOptions.DEFAULT);
System.out.println("========" + response);
}
}
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
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
# 2.3.2 检查索引是否存在
import com.tingyi.utils.EsClient;
import org.elasticsearch.action.admin.indices.alias.get.GetAliasesRequest;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.support.master.AcknowledgedResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.CreateIndexResponse;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.json.JsonXContent;
import org.junit.Test;
import java.io.IOException;
public class TestIndexManage {
//es连接
@Autowired
private RestHighLevelClient restHighLevelClient;
//索引库名字
private String index = "person";
/**
* 查看索引是否存在
* @throws IOException
*/
@Test
public void testIndexExists() throws IOException {
//1. 准备Get请求对象
GetAliasesRequest request = new GetAliasesRequest();
//将索引名字加入到请求对象中
request.indices(index);
//2. 通过client去操作
boolean exists = restHighLevelClient.indices().existsAlias(request, RequestOptions.DEFAULT);
//3. 输出
System.out.println(exists);
}
}
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
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
# 2.3.3 删除索引
import com.tingyi.utils.EsClient;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.support.master.AcknowledgedResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.CreateIndexResponse;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.json.JsonXContent;
import org.junit.Test;
public class TestIndexManage {
//es连接
@Autowired
private RestHighLevelClient restHighLevelClient;
//索引库名字
private String index = "person";
/**
* 删除索引
* @throws Exception
*/
@Test
public void testDeleteIndex() throws Exception{
//1. 准备删除索引请求对象
DeleteIndexRequest request = new DeleteIndexRequest();
//将需要删除的索引名字加入到请求对象中
request.indices(index);
//2. 通过client对象执行
AcknowledgedResponse delete = restHighLevelClient.indices().delete(request, RequestOptions.DEFAULT);
//3. 获取返回结果
System.out.println(delete.isAcknowledged());
}
}
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
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
# 2.4 Java操作文档
# 查询所有文档命令
GET book/_search
{
"query": {
"match_all": {}
}
}
1
2
3
4
5
6
7
2
3
4
5
6
7
# 2.4.1 添加文档操作
import com.fasterxml.jackson.databind.ObjectMapper;
import com.tingyi.utils.EsClient;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.xcontent.XContentType;
import org.junit.Test;
import pojo.Person;
import java.io.IOException;
import java.util.Date;
public class TestSimple {
//json转换工具对象
private ObjectMapper mapper = new ObjectMapper();
//es连接
@Autowired
private RestHighLevelClient restHighLevelClient;
//索引名字
private String index = "person";
/**
* 添加文档, 存入数据
* @throws IOException
*/
@Test
public void testCreateDoc() throws IOException {
//1. 准备一个person数据
Person person = new Person("1", "张三", 23, new Date());
//2. 将person实体转换成json格式
String json = mapper.writeValueAsString(person);
//3. 准备一个request对象, 指定索引名字(手动指定id)
IndexRequest request = new IndexRequest(index);
//4. 手动指定id, 将json数据存入请求对象中, XContentType.JSON为存入数据类型
request.id(person.getId()).source(json, XContentType.JSON);
//5. 通过client对象执行添加
IndexResponse resp = restHighLevelClient.index(request, RequestOptions.DEFAULT);
//6. 输出返回结果
System.out.println(resp.getResult().toString());
}
}
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
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
# 2.4.2 修改文档
import com.fasterxml.jackson.databind.ObjectMapper;
import com.tingyi.utils.EsClient;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.xcontent.XContentType;
import org.junit.Test;
import pojo.Person;
import java.io.IOException;
import java.util.Date;
public class TestSimple {
//json转换工具对象
private ObjectMapper mapper = new ObjectMapper();
//es连接
@Autowired
private RestHighLevelClient restHighLevelClient;
//索引名字
private String index = "person";
/**
* 修改文档数据
*/
@Test
public void testUpdateDoc() throws Exception {
//1. 准备一个person数据
Person person = new Person("1", "青龙", 23, new Date());
//2. 将person实体转换成json格式
String json = mapper.writeValueAsString(person);
//2. 创建修改请求对象, 第一个参数: 索引名字, 第二个参数:修改的文档id
UpdateRequest request = new UpdateRequest(index, person.getId());
//设置修改后的内容, 第二个参数: 文档数据类型
request.doc(json, XContentType.JSON);
//3. 通过client对象执行
UpdateResponse update = restHighLevelClient.update(request, RequestOptions.DEFAULT);
//4. 输出返回结果
System.out.println(update.getResult().toString());
}
}
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
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
# 2.4.3 删除文档
import com.fasterxml.jackson.databind.ObjectMapper;
import com.tingyi.utils.EsClient;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.xcontent.XContentType;
import org.junit.Test;
import pojo.Person;
import java.io.IOException;
import java.util.Date;
public class TestSimple {
//json转换工具对象
private ObjectMapper mapper = new ObjectMapper();
//es连接
@Autowired
private RestHighLevelClient restHighLevelClient;
//索引名字
private String index = "person";
/**
* 根据id删除文档
* @throws IOException
*/
@Test
public void testDeleteDoc() throws Exception {
//1. 封装用于删除的请求对象, 第一参数:索引名字, 第二参数:文档id
DeleteRequest request = new DeleteRequest(index, "1");
//2. client执行
DeleteResponse resp = restHighLevelClient.delete(request, RequestOptions.DEFAULT);
//3. 输出结果
System.out.println(resp.getResult().toString());
}
}
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
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
# 2.5 Java批量操作文档
# 2.5.1 批量添加
import com.fasterxml.jackson.databind.ObjectMapper;
import com.tingyi.utils.EsClient;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.xcontent.XContentType;
import org.junit.Test;
import pojo.Person;
import java.io.IOException;
import java.util.Date;
public class TestSimple {
//json转换工具对象
private ObjectMapper mapper = new ObjectMapper();
//es连接
@Autowired
private RestHighLevelClient restHighLevelClient;
//索引名字
private String index = "person";
/**
* 批量添加数据
* @throws IOException
*/
@Test
public void testBulkCreateDoc() throws IOException {
//1. 准备多个person实体数据
Person p1 = new Person("1", "张三", 23, new Date());
Person p2 = new Person("2", "李四", 24, new Date());
Person p3 = new Person("3", "王五", 25, new Date());
//2. 将实体数据转换成json格式
String json1 = mapper.writeValueAsString(p1);
String json2 = mapper.writeValueAsString(p2);
String json3 = mapper.writeValueAsString(p3);
//3. 创建批量执行请求对象,将准备好的数据封装进去
BulkRequest request = new BulkRequest();
request.add(new IndexRequest(index).id(p1.getId()).source(json1, XContentType.JSON));
request.add(new IndexRequest(index).id(p2.getId()).source(json2, XContentType.JSON));
request.add(new IndexRequest(index).id(p3.getId()).source(json3, XContentType.JSON));
//4. 用client执行
BulkResponse resp = restHighLevelClient.bulk(request, RequestOptions.DEFAULT);
//5. 输出结果
System.out.println(resp.toString());
}
}
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
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
# 2.5.2 批量删除
import com.fasterxml.jackson.databind.ObjectMapper;
import com.tingyi.utils.EsClient;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.xcontent.XContentType;
import org.junit.Test;
import pojo.Person;
import java.io.IOException;
import java.util.Date;
public class TestSimple {
//json转换工具对象
private ObjectMapper mapper = new ObjectMapper();
//es连接
@Autowired
private RestHighLevelClient restHighLevelClient;
//索引名字
private String index = "person";
/**
* 批量删除文档数据
* @throws IOException
*/
@Test
public void bulkDeleteDoc() throws IOException {
//1. 封装Request对象
BulkRequest request = new BulkRequest();
request.add(new DeleteRequest(index,"1"));
request.add(new DeleteRequest(index,"2"));
request.add(new DeleteRequest(index,"3"));
//2. client执行
BulkResponse resp = restHighLevelClient.bulk(request, RequestOptions.DEFAULT);
//3. 输出
System.out.println(resp);
}
}
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
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