0%

【ElasticSearch】Java整合ES

Java整合ES


1 环境准备

1.1 依赖

  • 演示的ES版本为8.x版本,8.x版本抛弃了rest-high-level-client的依赖的使用,改用新的依赖,若ES版本为8.x之前的,查看rest-high-level-client对应的使用
1
2
3
4
5
6
7
8
9
10
11
12
<!-- es-java整合 -->
<dependency>
<groupId>co.elastic.clients</groupId>
<artifactId>elasticsearch-java</artifactId>
<version>8.1.2</version>
</dependency>
<!-- jackson-json处理 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.13.2.2</version>
</dependency>

1.2 连接ES

  • 因为连接ES比较常用,直接封装为工具类
1
2
3
4
5
6
7
8
9
10
11
public class ESUtil {
// 获取ES客户端
public static ElasticsearchClient getEsClient() {
RestClient restClient = RestClient.builder(
// 地址, 端口, 通信协议(http/https)
new HttpHost("localhost", 9200, "http")
).build();
RestClientTransport restClientTransport = new RestClientTransport(restClient, new JacksonJsonpMapper());
return new ElasticsearchClient(restClientTransport);
}
}

2 索引使用

2.1 创建索引

1
2
3
4
5
6
7
// 创建索引
@Test
public void createIndex() throws Exception{
ElasticsearchClient esClient = ESUtil.getEsClient();
CreateIndexResponse createIndexResponse = esClient.indices().create(c -> c.index("user"));
System.out.println(createIndexResponse);
}

2.2 查询索引

1
2
3
4
5
6
7
8
9
// 查询索引
@Test
public void getIndex() throws Exception{
ElasticsearchClient esClient = ESUtil.getEsClient();
GetIndexResponse getIndexResponse = esClient.indices().get(i -> i.index("user"));
// 获取响应数据
IndexState indexState = getIndexResponse.result().get("user");
System.out.println(indexState);
}

2.3 删除索引

1
2
3
4
5
6
7
// 删除索引
@Test
public void deleteIndex() throws Exception {
ElasticsearchClient esClient = ESUtil.getEsClient();
DeleteIndexResponse deleteIndexResponse = esClient.indices().delete(i -> i.index("user"));
System.out.println(deleteIndexResponse);
}

3 文档使用

  • 创建一个User类,当作文档存储的数据
1
2
3
4
5
6
7
8
9
10
// 需要引入lombok依赖
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
private Integer id;
private String name;
private Integer age;
private String sex;
}

3.1 创建文档

1
2
3
4
5
6
7
8
// 创建文档
@Test
public void createDocument() throws Exception{
ElasticsearchClient esClient = ESUtil.getEsClient();
User user = new User(1001, "letere", 18, "男");
CreateResponse createResponse = esClient.create(i -> i.index("user").id("1002").document(user));
System.out.println(createResponse);
}

3.2 更新文档

1
2
3
4
5
6
7
8
// 更新文档
@Test
public void updateDocument() throws Exception {
ElasticsearchClient esClient = ESUtil.getEsClient();
User user = new User(1001, "letere", 18, "女");
UpdateResponse<User> updateResponse = esClient.update(i -> i.index("user").id("1001").doc(user), User.class);
System.out.println(updateResponse);
}

3.3 查询文档

1
2
3
4
5
6
7
// 查询文档
@Test
public void getDocument() throws Exception {
ElasticsearchClient esClient = ESUtil.getEsClient();
GetResponse<User> getResponse = esClient.get(i -> i.index("user").id("1001"), User.class);
System.out.println(getResponse.source());
}

3.4 删除文档

1
2
3
4
5
6
7
// 删除文档
@Test
public void deleteDocument() throws Exception {
ElasticsearchClient esClient = ESUtil.getEsClient();
DeleteResponse deleteResponse = esClient.delete(i -> i.index("user").id("1001"));
System.out.println(deleteResponse);
}

4 文档批量处理

4.1 批量创建

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// 批量创建文档
@Test
public void batchCreateDocument() throws Exception {
ElasticsearchClient esClient = ESUtil.getEsClient();
List<User> users = new ArrayList<>();
users.add(new User(1001, "letere", 18, "男"));
users.add(new User(1002, "glucat", 22, "男"));
users.add(new User(1003, "咕料", 30, "男"));
users.add(new User(1004, "C酱", 28, "女"));
// 转成List<BulkOperation>
List<BulkOperation> bulkOperations = new ArrayList<>();
for (User user : users) {
bulkOperations.add(BulkOperation.of(
b -> b.create(
d -> d.id(user.getId().toString()).document(user)
)
));
}
BulkResponse response = esClient.bulk(i -> i.index("user").operations(bulkOperations));
System.out.println(response.items());
}

4.2 批量删除

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 批量删除文档
@Test
public void batchDeleteDocument() throws Exception {
ElasticsearchClient esClient = ESUtil.getEsClient();
String[] ids = new String[]{"1001", "1002"};
// 转成List<BulkOperation>
List<BulkOperation> bulkOperations = new ArrayList<>();
for (String id : ids) {
bulkOperations.add(BulkOperation.of(
b -> b.delete(
d -> d.id(id)
)
));
}
BulkResponse response = esClient.bulk(i -> i.index("user").operations(bulkOperations));
System.out.println(response.items());
}

5 文档进阶查询

5.1 全量查询

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 全量查询
@Test
public void queryAll() throws Exception{
ElasticsearchClient esClient = ESUtil.getEsClient();
SearchResponse<User> searchResponse = esClient.search(
s -> s.index("user")
.query(q -> q
.matchAll(m -> m)),
User.class
);
for (Hit<User> userHit : searchResponse.hits().hits()) {
System.out.println(userHit.source());
}
}

5.2 条件查询

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 条件查询
@Test
public void wrapperQuery() throws Exception {
ElasticsearchClient esClient = ESUtil.getEsClient();
SearchResponse<User> searchResponse = esClient.search(
s -> s.index("user")
.query(q -> q
// term为完全匹配查询, match为分词匹配
// 查询的字段有中文时,field里填写'字段名.keyword',例age.keyword
.term(t -> t
.field("age")
.value(30))),
User.class
);
for (Hit<User> userHit : searchResponse.hits().hits()) {
System.out.println(userHit.source());
}
}

5.3 组合条件查询

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
// 组合条件查询
@Test
public void boolQuery() throws Exception {
ElasticsearchClient esClient = ESUtil.getEsClient();
SearchResponse<User> searchResponse = esClient.search(
s -> s.index("user")
.query(q -> q
.bool(b -> b
// must类似sql的and,should类似sql的or
.must(m -> m
.term(t -> t
.field("sex.keyword")
.value("男"))
)
.must(m -> m
.match(ma -> ma
.field("name")
.query("letere"))
))),
User.class
);
for (Hit<User> userHit : searchResponse.hits().hits()) {
System.out.println(userHit.source());
}
}

5.4 范围查询

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 范围查询
@Test
public void rangeQuery() throws Exception {
ElasticsearchClient esClient = ESUtil.getEsClient();
SearchResponse<User> searchResponse = esClient.search(
s -> s.index("user")
.query(q -> q
.range(r -> r
.field("age")
.gt(JsonData.of(20))
.lt(JsonData.of(30)))),
User.class
);
for (Hit<User> userHit : searchResponse.hits().hits()) {
System.out.println(userHit.source());
}
}

5.5 模糊查询

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 模糊查询
@Test
public void fuzzyQuery() throws Exception {
ElasticsearchClient esClient = ESUtil.getEsClient();
SearchResponse<User> searchResponse = esClient.search(
s -> s.index("user")
.query(q -> q
.fuzzy(f -> f
.field("name")
.value("lete")
.fuzziness("2"))), // 偏差字符长度,偏差长度<=2的,可以查询出来
User.class
);
for (Hit<User> userHit : searchResponse.hits().hits()) {
System.out.println(userHit.source());
}
}

5.6 分页查询

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 分页查询
@Test
public void pageQuery() throws Exception {
ElasticsearchClient esClient = ESUtil.getEsClient();
SearchResponse<User> searchResponse = esClient.search(
s -> s.index("user")
.query(q -> q
.matchAll(m -> m))
.from(0)
.size(2),
User.class
);
for (Hit<User> userHit : searchResponse.hits().hits()) {
System.out.println(userHit.source());
}
}

5.7 排序查询

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 排序查询
@Test
public void sortQuery() throws Exception {
ElasticsearchClient esClient = ESUtil.getEsClient();
SearchResponse<User> searchResponse = esClient.search(
s -> s.index("user")
.query(q -> q
.matchAll(m -> m))
.sort(so -> so
.field(f -> f
.field("age")
.order(SortOrder.Desc))),
User.class
);
for (Hit<User> userHit : searchResponse.hits().hits()) {
System.out.println(userHit.source());
}
}

5.8 指定字段查询

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 指定字段查询
@Test
public void fieldQuery() throws Exception {
ElasticsearchClient esClient = ESUtil.getEsClient();
SearchResponse<User> searchResponse = esClient.search(
s -> s.index("user")
.query(q -> q
.matchAll(m -> m))
.source(so -> so
.filter(f -> f
.includes("name", "age", "sex")
.excludes(""))),
User.class
);
for (Hit<User> userHit : searchResponse.hits().hits()) {
System.out.println(userHit.source());
}
}

5.9 高亮查询

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 高亮查询
@Test
public void highLightQuery() throws Exception {
ElasticsearchClient esClient = ESUtil.getEsClient();
SearchResponse<User> searchResponse = esClient.search(
s -> s.index("user")
.query(q -> q
.term(t -> t
.field("name.keyword")
.value("咕料")))
.highlight(h -> h
.fields("name.keyword", f -> f
.preTags("<font color='red'>")
.postTags("</font>"))),
User.class
);
for (Hit<User> userHit : searchResponse.hits().hits()) {
System.out.println(userHit.highlight());
}
}

5.10 聚合查询

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 聚合查询
@Test
public void groupQuery() throws Exception {
ElasticsearchClient esClient = ESUtil.getEsClient();
SearchResponse<User> searchResponse = esClient.search(
s -> s.index("user")
.aggregations("sexCount", a -> a.terms(t -> t.field("sex.keyword"))),
User.class
);
// 根据查询的字段数据类型选择对应的terms,string选择sterms,数字选择lterms
for (StringTermsBucket stringTermsBucket : searchResponse.aggregations().get("sexCount").sterms().buckets().array()) {
System.out.println(stringTermsBucket.key() + ":" + stringTermsBucket.docCount());
}
}