Java API 方式操作 Elasticsearch
准备项目
创建 Maven 项目,在 IDEA 开发工具中创建 Maven 项目(模块), 取名叫 es。
修改 pom 文件,增加 Maven 依赖关系
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<dependencies>
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>7.8.0</version>
</dependency>
<!-- elasticsearch 的客户端 -->
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>7.8.0</version>
</dependency>
<!-- elasticsearch 依赖 2.x 的 log4j -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.8.2</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.8.2</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.9</version>
</dependency>
<!-- junit 单元测试 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
REST 客户端
- ES 提供了两个 JAVA REST client 版本
- Java Low Level REST Client: 低级别的 REST 客户端,通过 http 与集群交互,用户需自己编组请求 JSON 串,及解析响应 JSON 串。兼容所有 ES 版本。
- Java High Level REST Client: 高级别的 REST 客户端,基于低级别的 REST 客户端,增加了编组请求 JSON 串、解析响应 JSON 串等相关 api。使用的版本需要保持和 ES 服务端的版本一致,否则会有版本问题。
Low Level Client
High Level Client
从 6.0.0 开始加入的,目的是以 java 面向对象的方式来进行请求、响应处理。
每个 API 支持 同步/异步 两种方式,同步方法直接返回一个结果对象。异步的方法以 async 为后缀,通过 listener 参数来通知结果。
API 及用法示例参考:https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/java-rest-high-supported-apis.html
兼容性说明:
- 依赖 java1.8 和 Elasticsearch core project
- 请使用与服务端 ES 版本一致的客户端版本
使用
创建 pers.fulsun.es.test._01_ESClient 类,代码中创建 Elasticsearch 客户端对象
初始化:给定集群的多个节点地址,将客户端负载均衡地向这个节点地址集发请求:
1
2
3
4
5
6
7
8
9
10
11
12
13
14public class _01_ESClient {
public static RestHighLevelClient getClient() {
RestHighLevelClient client = new RestHighLevelClient(
RestClient.builder(
// 9200 端口为 Elasticsearch 默认的 Web 通信端口
new HttpHost("localhost", 9200, "http"),
new HttpHost("localhost", 9201, "http")
)
);
return client;
}
}Client 不再使用了,记得关闭它:
1
2
3
4
5
6public static void main(String[] args) throws IOException {
RestHighLevelClient client = getClient();
System.out.println(client);
// 关闭客户端连接
client.close();
}
索引操作
- ES 服务器正常启动后,可以通过 Java API 客户端对象对 ES 索引进行操作
创建索引
代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22import java.io.IOException;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.CreateIndexResponse;
import pers.fulsun.es.test._01_ESClient;
public class _01_ESTest_Index_Create {
private static RestHighLevelClient client= _01_ESClient.getClient();;
public static void main(String[] args) throws IOException {
// 创建索引 - 请求对象
CreateIndexRequest request = new CreateIndexRequest("user1");
// 发送请求,获取响应
CreateIndexResponse response = client.indices().create(request, RequestOptions.DEFAULT);
boolean acknowledged = response.isAcknowledged();
// 响应状态
System.out.println("操作状态 = " + acknowledged);
// 关闭客户端连接
client.close();
}
}操作结果:
1
操作状态 = true
查找索引
代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import java.io.IOException;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.GetIndexRequest;
import org.elasticsearch.client.indices.GetIndexResponse;
import pers.fulsun.es.test._01_ESClient;
public class _02_ESTest_Index_Search {
private static RestHighLevelClient client = _01_ESClient.getClient();
public static void main(String[] args) throws IOException {
// 创建索引 - 请求对象
GetIndexRequest request = new GetIndexRequest("user");
// 发送请求,获取响应
GetIndexResponse getIndexResponse = client.indices().get(request, RequestOptions.DEFAULT);
// 响应状态
System.out.println(getIndexResponse.getAliases());
System.out.println(getIndexResponse.getMappings());
System.out.println(getIndexResponse.getSettings());
// 关闭客户端连接
client.close();
}
}操作结果:
1
2
3{user=[]}
{user=org.elasticsearch.cluster.metadata.MappingMetadata@90ad7867}
{user={"index.creation_date":"1637398010230","index.number_of_replicas":"1","index.number_of_shards":"1","index.provided_name":"user","index.uuid":"cG5E6L9jR8OwFiAXe0lNrw","index.version.created":"7080099"}}
删除索引
代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14public class _03_ESTest_Index_Delete {
private static RestHighLevelClient client = _01_ESClient.getClient();
public static void main(String[] args) throws IOException {
// 删除索引 - 请求对象
DeleteIndexRequest request = new DeleteIndexRequest("user");
// 发送请求,获取响应
AcknowledgedResponse response = client.indices().delete(request, RequestOptions.DEFAULT);
// 响应状态
System.out.println(response.isAcknowledged());
// 关闭客户端连接
client.close();
}
}操作结果:
1
true
文档操作
创建数据模型
添加 lombok 依赖
1
2
3
4
5<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.20</version>
</dependency>创建实体类
1
2
3
4
5
6
public class User {
private String name;
private String sex;
private Integer age;
}
新增文档
代码如下:
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
39package pers.fulsun.es.test._03_doc;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
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 pers.fulsun.es.test._01_ESClient;
import pers.fulsun.es.test.entity.User;
public class _01_ESTest_Doc_Insert {
private static RestHighLevelClient client = _01_ESClient.getClient();
public static void main(String[] args) throws IOException {
// 新增文档 - 请求对象
IndexRequest request = new IndexRequest();
// 设置索引及唯一性标识
request.index("user").id("1001");
// 创建数据对象
User user = new User();
user.setName("zhangsan");
user.setAge(30);
user.setSex("男");
ObjectMapper objectMapper = new ObjectMapper();
String productJson = objectMapper.writeValueAsString(user);
// 添加文档数据,数据格式为 JSON 格式
request.source(productJson, XContentType.JSON);
// 客户端发送请求,获取响应对象
IndexResponse response = client.index(request, RequestOptions.DEFAULT);
//// 3. 打印结果信息
System.out.println("_index:" + response.getIndex());
System.out.println("_id:" + response.getId());
System.out.println("_result:" + response.getResult());
// 关闭客户端连接
client.close();
}
}操作结果:
1
2
3_index:user
_id:1001
_result:CREATED
修改文档
代码如下:
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
31package pers.fulsun.es.test._03_doc;
import java.io.IOException;
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 pers.fulsun.es.test._01_ESClient;
public class _02_ESTest_Doc_Update {
private static RestHighLevelClient client = _01_ESClient.getClient();
public static void main(String[] args) throws IOException {
// 修改文档 - 请求对象
UpdateRequest request = new UpdateRequest();
// 配置修改参数
request.index("user").id("1001");
// 设置请求体,对数据进行修改
request.doc(XContentType.JSON, "sex", "女");
// 添加文档数据,数据格式为 JSON 格式
UpdateResponse response = client.update(request, RequestOptions.DEFAULT);
// 客户端发送请求,获取响应对象
//// 3. 打印结果信息
System.out.println("_index:" + response.getIndex());
System.out.println("_id:" + response.getId());
System.out.println("_result:" + response.getResult());
// 关闭客户端连接
client.close();
}
}操作结果:
1
2
3_index:user
_id:1001
_result:UPDATED
查询文档
代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15public class _03_ESTest_Doc_Search {
private static RestHighLevelClient client = _01_ESClient.getClient();
public static void main(String[] args) throws IOException {
GetRequest request = new GetRequest();
request.index("user").id("1004");
GetResponse response = client.get(request, RequestOptions.DEFAULT);
System.out.println(response.isExists());
System.out.println(response.getSourceAsString());
// 关闭客户端连接
client.close();
}
}操作结果:
1
2true
{"name":"wangwu1","age":40,"sex":"女"}
删除文档
代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15public class _04_ESTest_Doc_Delete {
private static RestHighLevelClient client = _01_ESClient.getClient();
public static void main(String[] args) throws IOException {
DeleteRequest request = new DeleteRequest();
request.index("user").id("1001");
DeleteResponse response = client.delete(request, RequestOptions.DEFAULT);
System.out.println(response.toString());
// 关闭客户端连接
client.close();
}
}操作结果:
1
DeleteResponse[index=user,type=_doc,id=1001,version=3,result=deleted,shards=ShardInfo{total=2, successful=1, failures=[]}]
批量插入
代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24public class _05_ESTest_Doc_Insert_Batch {
private static RestHighLevelClient client = _01_ESClient.getClient();
public static void main(String[] args) throws IOException {
// 批量插入数据
BulkRequest request = new BulkRequest();
request.add(new IndexRequest().index("user").id("1001").source(XContentType.JSON, "name", "zhangsan", "age",30,"sex","男"));
request.add(new IndexRequest().index("user").id("1002").source(XContentType.JSON, "name", "lisi", "age",30,"sex","女"));
request.add(new IndexRequest().index("user").id("1003").source(XContentType.JSON, "name", "wangwu", "age",40,"sex","男"));
request.add(new IndexRequest().index("user").id("1004").source(XContentType.JSON, "name", "wangwu1", "age",40,"sex","女"));
request.add(new IndexRequest().index("user").id("1005").source(XContentType.JSON, "name", "wangwu2", "age",50,"sex","男"));
request.add(new IndexRequest().index("user").id("1006").source(XContentType.JSON, "name", "wangwu3", "age",50,"sex","男"));
request.add(new IndexRequest().index("user").id("1007").source(XContentType.JSON, "name", "wangwu44", "age",60,"sex","男"));
request.add(new IndexRequest().index("user").id("1008").source(XContentType.JSON, "name", "wangwu555", "age",60,"sex","男"));
request.add(new IndexRequest().index("user").id("1009").source(XContentType.JSON, "name", "wangwu66666", "age",60,"sex","男"));
BulkResponse response = client.bulk(request, RequestOptions.DEFAULT);
System.out.println(response.getTook());
System.out.println(response.getItems());
// 关闭客户端连接
client.close();
}
}操作结果:
1
2180ms
[Lorg.elasticsearch.action.bulk.BulkItemResponse;@4b1d6571
批量删除
代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19public class _06_ESTest_Doc_Delete_Batch {
private static RestHighLevelClient client = _01_ESClient.getClient();
public static void main(String[] args) throws IOException {
// 批量删除数据
BulkRequest request = new BulkRequest();
request.add(new DeleteRequest().index("user").id("1001"));
request.add(new DeleteRequest().index("user").id("1002"));
request.add(new DeleteRequest().index("user").id("1003"));
BulkResponse response = client.bulk(request, RequestOptions.DEFAULT);
System.out.println(response.getTook());
System.out.println(response.getItems());
// 关闭客户端连接
client.close();
}
}操作结果:
1
2175ms
[Lorg.elasticsearch.action.bulk.BulkItemResponse;@1a20270e
高级查询
查询所有索引数据
QueryBuilders.matchAllQuery())
代码如下: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
46package pers.fulsun.es.test._04_search;
import java.io.IOException;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import pers.fulsun.es.test._01_ESClient;
public class _01_ESTest_Doc_Search_All {
private static RestHighLevelClient client = _01_ESClient.getClient();
public static void main(String[] args) throws IOException {
// 1. 查询索引的所有数据
SearchRequest request = new SearchRequest();
request.indices("user");
// 构造查询条件
SearchSourceBuilder builder = new SearchSourceBuilder();
builder.query(QueryBuilders.matchAllQuery());
// 添加查询条件到请求
request.source(builder);
// 发起查询
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
// 查询匹配
SearchHits hits = response.getHits();
System.out.println("took:" + response.getTook());
System.out.println("timeout:" + response.isTimedOut());
System.out.println("total:" + hits.getTotalHits());
System.out.println("MaxScore:" + hits.getMaxScore());
System.out.println("hits========>>");
for (SearchHit hit : hits) {
// 输出每条查询的结果信息
System.out.println(hit.getSourceAsString());
}
System.out.println("<<========");
// 关闭客户端连接
client.close();
}
}操作结果:
1
2
3
4
5
6
7
8
9
10
11
12took:1ms
timeout:false
total:6 hits
MaxScore:1.0
hits========>>
{"name":"wangwu1","age":40,"sex":"女"}
{"name":"wangwu2","age":50,"sex":"男"}
{"name":"wangwu3","age":50,"sex":"男"}
{"name":"wangwu44","age":60,"sex":"男"}
{"name":"wangwu555","age":60,"sex":"男"}
{"name":"wangwu66666","age":60,"sex":"男"}
<<========
关键字查询
term 查询
QueryBuilders.termQuery(...))
,代码如下: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
31public class _02_ESTest_Doc_Search_Term {
private static RestHighLevelClient client = _01_ESClient.getClient();
public static void main(String[] args) throws IOException {
// 创建搜索请求对象
SearchRequest request = new SearchRequest();
request.indices("user");
// 构建查询的请求体
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
// text 类型的中文可以使用 keyword 避免分词
sourceBuilder.query(QueryBuilders.termQuery("name.keyword", "wangwu3"));
request.source(sourceBuilder);
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
// 查询匹配
SearchHits hits = response.getHits();
System.out.println("took:" + response.getTook());
System.out.println("timeout:" + response.isTimedOut());
System.out.println("total:" + hits.getTotalHits());
System.out.println("MaxScore:" + hits.getMaxScore());
System.out.println("hits========>>");
for (SearchHit hit : hits) {
// 输出每条查询的结果信息
System.out.println(hit.getSourceAsString());
}
System.out.println("<<========");
// 关闭客户端连接
client.close();
}
}操作结果:
1
2
3
4
5
6
7took:3ms
timeout:false
total:1 hits
MaxScore:1.89712
hits========>>
{"name":"wangwu3","age":50,"sex":"男"}
<<========
分页查询
代码如下:
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
37public class _03_ESTest_Doc_Search_Page {
private static RestHighLevelClient client = _01_ESClient.getClient();
public static void main(String[] args) throws IOException {
// 创建搜索请求对象
SearchRequest request = new SearchRequest();
request.indices("user");
// 构建查询的请求体
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
sourceBuilder.query(QueryBuilders.matchAllQuery());
// 分页查询
// 当前页其实索引(第一条数据的顺序号为 0)
sourceBuilder.from(0);
// 每页显示多少条 size
sourceBuilder.size(2);
request.source(sourceBuilder);
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
// 查询匹配
SearchHits hits = response.getHits();
System.out.println("took:" + response.getTook());
System.out.println("timeout:" + response.isTimedOut());
System.out.println("total:" + hits.getTotalHits());
System.out.println("MaxScore:" + hits.getMaxScore());
System.out.println("hits========>>");
for (SearchHit hit : hits) {
// 输出每条查询的结果信息
System.out.println(hit.getSourceAsString());
}
System.out.println("<<========");
// 关闭客户端连接
client.close();
}
}操作结果:
1
2
3
4
5
6
7
8took:1ms
timeout:false
total:6 hits
MaxScore:1.0
hits========>>
{"name":"wangwu1","age":40,"sex":"女"}
{"name":"wangwu2","age":50,"sex":"男"}
<<========
数据排序
代码如下:
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
34public class _04_ESTest_Doc_Search_Sort {
private static RestHighLevelClient client = _01_ESClient.getClient();
public static void main(String[] args) throws IOException {
// 创建搜索请求对象
SearchRequest request = new SearchRequest();
request.indices("user");
// 构建查询的请求体
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
sourceBuilder.query(QueryBuilders.matchAllQuery());
// 排序
sourceBuilder.sort("age", SortOrder.ASC);
request.source(sourceBuilder);
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
// 查询匹配
SearchHits hits = response.getHits();
System.out.println("took:" + response.getTook());
System.out.println("timeout:" + response.isTimedOut());
System.out.println("total:" + hits.getTotalHits());
System.out.println("MaxScore:" + hits.getMaxScore());
System.out.println("hits========>>");
for (SearchHit hit : hits) {
// 输出每条查询的结果信息
System.out.println(hit.getSourceAsString());
}
System.out.println("<<========");
// 关闭客户端连接
client.close();
}
}操作结果:
1
2
3
4
5
6
7
8
9
10
11
12took:25ms
timeout:false
total:6 hits
MaxScore:NaN
hits========>>
{"name":"wangwu1","age":40,"sex":"女"}
{"name":"wangwu2","age":50,"sex":"男"}
{"name":"wangwu3","age":50,"sex":"男"}
{"name":"wangwu44","age":60,"sex":"男"}
{"name":"wangwu555","age":60,"sex":"男"}
{"name":"wangwu66666","age":60,"sex":"男"}
<<========
过滤字段
代码如下:
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
36public class _05_ESTest_Doc_Search_Filter {
private static RestHighLevelClient client = _01_ESClient.getClient();
public static void main(String[] args) throws IOException {
// 创建搜索请求对象
SearchRequest request = new SearchRequest();
request.indices("user");
// 构建查询的请求体
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
sourceBuilder.query(QueryBuilders.matchAllQuery());
// 查询字段过滤
String[] excludes = {"age"};
String[] includes = {"name", "age"};
sourceBuilder.fetchSource(includes, excludes);
request.source(sourceBuilder);
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
// 查询匹配
SearchHits hits = response.getHits();
System.out.println("took:" + response.getTook());
System.out.println("timeout:" + response.isTimedOut());
System.out.println("total:" + hits.getTotalHits());
System.out.println("MaxScore:" + hits.getMaxScore());
System.out.println("hits========>>");
for (SearchHit hit : hits) {
// 输出每条查询的结果信息
System.out.println(hit.getSourceAsString());
}
System.out.println("<<========");
// 关闭客户端连接
client.close();
}
}操作结果:
1
2
3
4
5
6
7
8
9
10
11
12took:1ms
timeout:false
total:6 hits
MaxScore:1.0
hits========>>
{"name":"wangwu1"}
{"name":"wangwu2"}
{"name":"wangwu3"}
{"name":"wangwu44"}
{"name":"wangwu555"}
{"name":"wangwu66666"}
<<========
组合 (Bool) 查询
代码如下:
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
43public class _06_ESTest_Doc_Search_Bool {
private static RestHighLevelClient client = _01_ESClient.getClient();
public static void main(String[] args) throws IOException {
// 创建搜索请求对象
SearchRequest request = new SearchRequest();
request.indices("user");
// 构建查询的请求体
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
// 必须包含
boolQueryBuilder.must(QueryBuilders.matchQuery("age", "60"));
// 一定不含
// boolQueryBuilder.mustNot(QueryBuilders.matchQuery("name", "wangwu66666"));
// 可能包含
boolQueryBuilder.should(QueryBuilders.termQuery("sex", "女"));
boolQueryBuilder.should(QueryBuilders.termQuery("name.keyword", "wangwu44"));
// 只有 must 和 should 会失效,满足任意一个 should 即可
boolQueryBuilder.minimumShouldMatch(1);
sourceBuilder.query(boolQueryBuilder);
request.source(sourceBuilder);
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
// 查询匹配
SearchHits hits = response.getHits();
System.out.println("took:" + response.getTook());
System.out.println("timeout:" + response.isTimedOut());
System.out.println("total:" + hits.getTotalHits());
System.out.println("MaxScore:" + hits.getMaxScore());
System.out.println("hits========>>");
for (SearchHit hit : hits) {
// 输出每条查询的结果信息
System.out.println(hit.getSourceAsString());
}
System.out.println("<<========");
// 关闭客户端连接
client.close();
}
}操作结果:
1
2
3
4
5
6
7
8took:2ms
timeout:false
total:2 hits
MaxScore:2.5404449
hits========>>
{"name":"wangwu44","age":60,"sex":"男"}
{"name":"wangwu555","age":60,"sex":"女"}
<<========
范围查询
代码如下:
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
37public class _07_ESTest_Doc_Search_Range {
private static RestHighLevelClient client = _01_ESClient.getClient();
public static void main(String[] args) throws IOException {
// 创建搜索请求对象
SearchRequest request = new SearchRequest();
request.indices("user");
// 构建查询的请求体
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
RangeQueryBuilder rangeQuery = QueryBuilders.rangeQuery("age");
// 大于等于
rangeQuery.gte("30");
// 小于等于
rangeQuery.lte("40");
sourceBuilder.query(rangeQuery);
request.source(sourceBuilder);
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
// 查询匹配
SearchHits hits = response.getHits();
System.out.println("took:" + response.getTook());
System.out.println("timeout:" + response.isTimedOut());
System.out.println("total:" + hits.getTotalHits());
System.out.println("MaxScore:" + hits.getMaxScore());
System.out.println("hits========>>");
for (SearchHit hit : hits) {
// 输出每条查询的结果信息
System.out.println(hit.getSourceAsString());
}
System.out.println("<<========");
// 关闭客户端连接
client.close();
}
}操作结果:
1
2
3
4
5
6
7took:3ms
timeout:false
total:1 hits
MaxScore:1.0
hits========>>
{"name":"wangwu1","age":40,"sex":"女"}
<<========
模糊查询
代码如下:
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
30public class _08_ESTest_Doc_Search_Fuzzy {
private static RestHighLevelClient client = _01_ESClient.getClient();
public static void main(String[] args) throws IOException {
// 创建搜索请求对象
SearchRequest request = new SearchRequest();
request.indices("user");
// 构建查询的请求体
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
sourceBuilder.query(QueryBuilders.fuzzyQuery("name", "wangwu").fuzziness(Fuzziness.TWO));
request.source(sourceBuilder);
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
// 查询匹配
SearchHits hits = response.getHits();
System.out.println("took:" + response.getTook());
System.out.println("timeout:" + response.isTimedOut());
System.out.println("total:" + hits.getTotalHits());
System.out.println("MaxScore:" + hits.getMaxScore());
System.out.println("hits========>>");
for (SearchHit hit : hits) {
// 输出每条查询的结果信息
System.out.println(hit.getSourceAsString());
}
System.out.println("<<========");
// 关闭客户端连接
client.close();
}
}操作结果:
1
2
3
4
5
6
7
8
9
10
11took:4ms
timeout:false
total:4 hits
MaxScore:1.2837042
hits========>>
{"name":"wangwu1","age":40,"sex":"女"}
{"name":"wangwu2","age":50,"sex":"男"}
{"name":"wangwu3","age":50,"sex":"男"}
{"name":"wangwu44","age":60,"sex":"男"}
<<========
高亮查询
代码如下:
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
48public class _09_ESTest_Doc_Search_HighLight {
private static RestHighLevelClient client = _01_ESClient.getClient();
public static void main(String[] args) throws IOException {
// 创建搜索请求对象
SearchRequest request = new SearchRequest();
request.indices("user");
// 构建查询的请求体
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
// 构建查询方式
TermsQueryBuilder termsQueryBuilder = QueryBuilders.termsQuery("name", "wangwu1");
sourceBuilder.query(termsQueryBuilder);
// 构建高亮字段
HighlightBuilder highlightBuilder = new HighlightBuilder();
// 设置标签前缀
highlightBuilder.preTags("<font color='red'>");
// 设置标签后缀
highlightBuilder.postTags("</font>");
// 设置高亮字段
highlightBuilder.field("name");
// 设置高亮构建对象
sourceBuilder.highlighter(highlightBuilder);
request.source(sourceBuilder);
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
// 查询匹配
SearchHits hits = response.getHits();
System.out.println("took:" + response.getTook());
System.out.println("timeout:" + response.isTimedOut());
System.out.println("total:" + hits.getTotalHits());
System.out.println("MaxScore:" + hits.getMaxScore());
System.out.println("hits========>>");
for (SearchHit hit : hits) {
// 输出每条查询的结果信息
System.out.println(hit.getSourceAsString());
// 打印高亮结果
Map<String, HighlightField> highlightFields = hit.getHighlightFields();
System.out.println(highlightFields);
}
System.out.println("<<========");
// 关闭客户端连接
client.close();
}
}操作结果:
1
2
3
4
5
6
7
8took:3ms
timeout:false
total:1 hits
MaxScore:1.0
hits========>>
{"name":"wangwu1","age":40,"sex":"女"}
{name=[name], fragments[[<font color='red'>wangwu1</font>]]}
<<========
聚合查询
- 聚合操作分为指标聚合和分组聚合。RestHighLevelClient 可以使用 API 方法也可以使用 script 脚本进行聚合。
最大年龄
代码如下:
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
30public class _010_ESTest_Doc_Search_Max {
private static RestHighLevelClient client = _01_ESClient.getClient();
public static void main(String[] args) throws IOException {
// 构建查询的请求体
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
// 构建聚合查询方式
sourceBuilder.aggregation(AggregationBuilders.max("maxAge").field("age"));
// 创建搜索请求对象
SearchRequest request = new SearchRequest();
request.indices("user");
sourceBuilder.size(0);
request.source(sourceBuilder);
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
System.out.println("took:" + response.getTook());
System.out.println("timeout:" + response.isTimedOut());
System.out.println("aggregations========>>");
// 和之前不同的是这里需要 getAggregations 获取聚合后的数据
Aggregations aggregations = response.getAggregations();
//从查询结果中获取刚才定义的最大值的名称
Max maxAge = aggregations.get("maxAge");
System.out.println(maxAge.getValue());
System.out.println("<<========");
// 关闭客户端连接
client.close();
}
}操作结果:
1
2
3
4
5took:2ms
timeout:false
aggregations========>>
60.0
<<========
stats 聚合
stats 聚合,对某个字段一次性返回 count,max,min,avg 和 sum 五个指标
代码如下:
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
37import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.metrics.Stats;
public class _010_ESTest_Doc_Search_Stats {
private static RestHighLevelClient client = _01_ESClient.getClient();
public static void main(String[] args) throws IOException {
// 构建查询的请求体
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
// 构建聚合查询方式
sourceBuilder.aggregation(AggregationBuilders.stats("stats_age").field("age"));
// 创建搜索请求对象
SearchRequest request = new SearchRequest();
request.indices("user");
sourceBuilder.size(0);
request.source(sourceBuilder);
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
System.out.println("took:" + response.getTook());
System.out.println("timeout:" + response.isTimedOut());
System.out.println("aggregations========>>");
// 和之前不同的是这里需要 getAggregations 获取聚合后的数据
Aggregations aggregations = response.getAggregations();
//从查询结果中获取刚才定义的最大值的名称
Stats stats = aggregations.get("stats_age");
System.out.println("count:"+stats.getCount());
System.out.println("min:"+stats.getMin());
System.out.println("max:"+stats.getMax());
System.out.println("avg:"+stats.getAvg());
System.out.println("sum:"+stats.getSum());
System.out.println("<<========");
// 关闭客户端连接
client.close();
}
}操作结果:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17took:1ms
timeout:false
aggregations========>>
count:6
min:40.0
max:60.0
avg:53.333333333333336
sum:320.0
<<========took:1ms
timeout:false
aggregations========>>
count:6
min:40.0
max:60.0
avg:53.333333333333336
sum:320.0
<<========
分组统计
代码如下:
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
56public class _011_ESTest_Doc_Search_Group {
private static RestHighLevelClient client = _01_ESClient.getClient();
public static void main(String[] args) throws IOException {
// 构建查询的请求体
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
// 构建聚合查询方式
TermsAggregationBuilder aggregationBuilder = AggregationBuilders
.terms("age_tr").field("age"). //桶分组
//求总数:可以从结果获取
// subAggregation(AggregationBuilders.count("count_age").field("age")).
subAggregation(AggregationBuilders.sum("sum_age").field("age")). //求和
subAggregation(AggregationBuilders.avg("avg_age").field("age")); //求平均值
sourceBuilder.aggregation(aggregationBuilder);
// 创建搜索请求对象
SearchRequest request = new SearchRequest();
// 不输出原始数据
sourceBuilder.size(0);
// 打印 dsl 语句
System.out.println(("dsl:" + sourceBuilder.toString()));
// 设置索引以及填充语句
request.indices("user");
request.source(sourceBuilder);
// 发送请求
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
System.out.println("took:" + response.getTook());
System.out.println("timeout:" + response.isTimedOut());
System.out.println("aggregations========>>");
// 和之前不同的是这里需要 getAggregations 获取聚合后的数据
Aggregations aggregations = response.getAggregations();
//ParsedTerms 有 long double String 三种类型
ParsedLongTerms parsedStringTerms = aggregations.get("age_tr");
List<? extends Bucket> buckets = parsedStringTerms.getBuckets();
for (Terms.Bucket bucket : buckets) {
//key 的数据
String key = bucket.getKey().toString();
// 分组的数据 = count
long docCount = bucket.getDocCount();
//获取数据
Aggregations bucketAggregations = bucket.getAggregations();
// long count = ((ParsedValueCount) bucketAggregations.get("count_age")).getValue();
ParsedSum sum = bucketAggregations.get("sum_age");
ParsedAvg avg = bucketAggregations.get("avg_age");
System.out.println(
key + ": count:"
+ docCount + ", sum:"
+ sum.getValue() + ", avg:"
+ avg.getValue());
}
// 关闭客户端连接
client.close();
}
}操作结果:
1
2
3
4
5
6
7dsl:{"size":0,"aggregations":{"age_tr":{"terms":{"field":"age","size":10,"min_doc_count":1,"shard_min_doc_count":0,"show_term_doc_count_error":false,"order":[{"_count":"desc"},{"_key":"asc"}]},"aggregations":{"sum_age":{"sum":{"field":"age"}},"avg_age":{"avg":{"field":"age"}}}}}}
took:4ms
timeout:false
aggregations========>>
60: count:3, sum:180.0, avg:60.0
50: count:2, sum:100.0, avg:50.0
40: count:1, sum:40.0, avg:40.0