Elasticsearch03——Java API

 Elasticsearch 软件是由 Java 语言开发的,所以也可以通过 Java API 的方式对 Elasticsearch 服务进行访问。

一、项目依赖
<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 客户端对象。

// 构建客户端对象
RestClientBuilder builder = RestClient.builder(new HttpHost("localhost", 9200, "http"));
// 创建高级Rest客户端对象
RestHighLevelClient client = new RestHighLevelClient(builder);
//...
// 关闭客户端连接
client.close();
二、索引操作
1、创建索引
CreateIndexRequest request = new CreateIndexRequest("user");
CreateIndexResponse response = client.indices().create(request, RequestOptions.DEFAULT);
boolean acknowledged = response.isAcknowledged();
System.out.println("操作状态 = " + acknowledged);

 若创建一个已经存在的索引则会抛出异常:resource_already_exists_exception,因此在创建索引的时候最好使用try…catch以便进行异常处理

Exception in thread "main" [user/wmpT3jX2Sz--gLtjyuyB_Q] ElasticsearchStatusException[Elasticsearch exception [type=resource_already_exists_exception, reason=index [user/wmpT3jX2Sz--gLtjyuyB_Q] already exists]]
	at org.elasticsearch.rest.BytesRestResponse.errorFromXContent(BytesRestResponse.java:177)
	at org.elasticsearch.client.RestHighLevelClient.parseEntity(RestHighLevelClient.java:1897)
	at org.elasticsearch.client.RestHighLevelClient.parseResponseException(RestHighLevelClient.java:1867)
	at org.elasticsearch.client.RestHighLevelClient.internalPerformRequest(RestHighLevelClient.java:1624)
	at org.elasticsearch.client.RestHighLevelClient.performRequest(RestHighLevelClient.java:1596)
	at org.elasticsearch.client.RestHighLevelClient.performRequestAndParseEntity(RestHighLevelClient.java:1563)
	at org.elasticsearch.client.IndicesClient.create(IndicesClient.java:139)
	at com.boom.pratice.es.Elasticsearch01_Client.main(Elasticsearch01_Client.java:20)
	Suppressed: org.elasticsearch.client.ResponseException: method [PUT], host [http://localhost:9200], URI [/user?master_timeout=30s&timeout=30s], status line [HTTP/1.1 400 Bad Request]
{"error":{"root_cause":[{"type":"resource_already_exists_exception","reason":"index [user/wmpT3jX2Sz--gLtjyuyB_Q] already exists","index_uuid":"wmpT3jX2Sz--gLtjyuyB_Q","index":"user"}],"type":"resource_already_exists_exception","reason":"index [user/wmpT3jX2Sz--gLtjyuyB_Q] already exists","index_uuid":"wmpT3jX2Sz--gLtjyuyB_Q","index":"user"},"status":400}
		at org.elasticsearch.client.RestClient.convertResponse(RestClient.java:283)
		at org.elasticsearch.client.RestClient.performRequest(RestClient.java:261)
		at org.elasticsearch.client.RestClient.performRequest(RestClient.java:235)
		at org.elasticsearch.client.RestHighLevelClient.internalPerformRequest(RestHighLevelClient.java:1611)
		... 4 more
2、查看索引
GetIndexRequest request = new GetIndexRequest("user");
GetIndexResponse response = client.indices().get(request, RequestOptions.DEFAULT);
Map<String, List<AliasMetadata>> aliases = response.getAliases();
Map<String, MappingMetadata> mappings = response.getMappings();
Map<String, Settings> settings = response.getSettings();
System.out.println(aliases);
System.out.println(mappings);
System.out.println(settings);
3、删除索引
DeleteIndexRequest request = new DeleteIndexRequest("user");
AcknowledgedResponse response = client.indices().delete(request, RequestOptions.DEFAULT);
System.out.println(response.isAcknowledged());

 删除不存在的索引时也会抛出异常:index_not_found_exception

Exception in thread "main" [hello] ElasticsearchStatusException[Elasticsearch exception [type=index_not_found_exception, reason=no such index [hello]]]
	at org.elasticsearch.rest.BytesRestResponse.errorFromXContent(BytesRestResponse.java:177)
	at org.elasticsearch.client.RestHighLevelClient.parseEntity(RestHighLevelClient.java:1897)
	at org.elasticsearch.client.RestHighLevelClient.parseResponseException(RestHighLevelClient.java:1867)
	at org.elasticsearch.client.RestHighLevelClient.internalPerformRequest(RestHighLevelClient.java:1624)
	at org.elasticsearch.client.RestHighLevelClient.performRequest(RestHighLevelClient.java:1581)
	at org.elasticsearch.client.RestHighLevelClient.performRequestAndParseEntity(RestHighLevelClient.java:1551)
	at org.elasticsearch.client.IndicesClient.delete(IndicesClient.java:108)
	at com.boom.pratice.es.Elasticsearch01_Client.main(Elasticsearch01_Client.java:75)
	Suppressed: org.elasticsearch.client.ResponseException: method [DELETE], host [http://localhost:9200], URI [/hello?master_timeout=30s&ignore_unavailable=false&expand_wildcards=open%2Cclosed&allow_no_indices=true&ignore_throttled=false&timeout=30s], status line [HTTP/1.1 404 Not Found]
{"error":{"root_cause":[{"type":"index_not_found_exception","reason":"no such index [hello]","resource.type":"index_or_alias","resource.id":"hello","index_uuid":"_na_","index":"hello"}],"type":"index_not_found_exception","reason":"no such index [hello]","resource.type":"index_or_alias","resource.id":"hello","index_uuid":"_na_","index":"hello"},"status":404}
		at org.elasticsearch.client.RestClient.convertResponse(RestClient.java:283)
		at org.elasticsearch.client.RestClient.performRequest(RestClient.java:261)
		at org.elasticsearch.client.RestClient.performRequest(RestClient.java:235)
		at org.elasticsearch.client.RestHighLevelClient.internalPerformRequest(RestHighLevelClient.java:1611)
		... 4 more
三、文档操作
创建数据模型
public class User {
    private String name;
    private Integer age;
    private String sex;
}
1、新增文档
IndexRequest request = new IndexRequest();
// 自定义id,user是索引名称
request.index("user").id("1001");
User user = new User();
user.setName("zhangsan");
user.setAge(30);
user.setSex("男");
ObjectMapper om = new ObjectMapper();
// 将数据转为JSON串,也可以使用fastjson等工具
String json = om.writeValueAsString(user);
// 以JSON格式添加数据,也支持YAML等格式
request.source(json, XContentType.JSON);
IndexResponse response = client.index(request, RequestOptions.DEFAULT);
System.out.println(response.getIndex());
System.out.println(response.getId());
System.out.println(response.getResult());
2、修改文档
UpdateRequest request = new UpdateRequest();
request.index("user").id("1001");
// 可以同时修改多个属性的值
request.doc(XContentType.JSON,"sex","女","age",32);
UpdateResponse response = client.update(request, RequestOptions.DEFAULT);
System.out.println(response.getIndex());
System.out.println(response.getId());
System.out.println(response.getResult());
3、查询文档
GetRequest request = new GetRequest();
GetRequest user = request.index("user").id("1001");
GetResponse response = client.get(user, RequestOptions.DEFAULT);
System.out.println(response.getIndex());
// type的默认值为_doc
System.out.println(response.getType());
System.out.println(response.getId());
// 可以获取到JSON格式的数据:{"name":"zhangsan","age":32,"sex":"女"}
System.out.println(response.getSourceAsString());
4、删除文档
DeleteRequest request = new DeleteRequest();
DeleteRequest user = request.index("user").id("1001");
DeleteResponse response = client.delete(user, RequestOptions.DEFAULT);
System.out.println(response.toString());

 删除不存在的文档时不会抛出异常,而是响应未找到文档,这和删除索引不同。

DeleteResponse[index=user,type=_doc,id=1,version=1,result=not_found,shards=ShardInfo{total=2, successful=1, failures=[]}]
5、批量操作
①批量新增
BulkRequest request = new BulkRequest();
// 已存在的id会变为覆盖操作
request.add(new IndexRequest("user").id("1001").source(XContentType.JSON,"name","ZhangSan"));
request.add(new IndexRequest("user").id("1002").source(XContentType.JSON,"name","lisi"));
request.add(new IndexRequest("user").id("1003").source(XContentType.JSON,"name","wangwu","age",33,"sex","男"));
BulkResponse response = client.bulk(request, RequestOptions.DEFAULT);
System.out.println(response.getTook());
System.out.println(response.getItems());

 注意使用IndexRequest对于已存在的id是会覆盖原有的文档数据,而非简单的修改。

②批量删除
BulkRequest request = new BulkRequest();
request.add(new DeleteRequest().index("user").id("1001"));
request.add(new DeleteRequest("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());
③批量混合操作
BulkRequest request = new BulkRequest();
request.add(new IndexRequest().index("user").id("1001").source(XContentType.JSON,"name","zhangsan","age",31,"sex","男"));
request.add(new DeleteRequest("user").id("1002"));
request.add(new UpdateRequest().index("user").id("1003").doc(XContentType.JSON,"name","王五","age",35,"sex","男"));
BulkResponse response = client.bulk(request, RequestOptions.DEFAULT);
System.out.println(response.getTook());
System.out.println(response.getItems());

 _bulk操作是可以同时操作多种类型的。

四、高级查询
1、请求体查询
①查询索引所有数据
// 创建搜索请求对象
SearchRequest request = new SearchRequest();
// 指定查询的索引
request.indices("user");
// 构建查询请求体
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
sourceBuilder.query(QueryBuilders.matchAllQuery());
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());
for (SearchHit hit : hits) {
    //输出每条查询的结果信息:转为JSON
    System.out.println(hit.getSourceAsString());
}
②term查询
// 创建搜索请求对象
SearchRequest request = new SearchRequest();
request.indices("user");
// 构建查询请求体
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
sourceBuilder.query(QueryBuilders.termQuery("age",30));
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());
for (SearchHit hit : hits) {
    //输出每条查询的结果信息:转为JSON
    System.out.println(hit.getSourceAsString());
}

 只是变更了请求体。

③分页查询
// 创建搜索请求对象
SearchRequest request = new SearchRequest();
request.indices("user");
// 构建查询请求体
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
sourceBuilder.query(QueryBuilders.matchAllQuery());
// 分页属性
sourceBuilder.from(0);
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());
for (SearchHit hit : hits) {
   //输出每条查询的结果信息:转为JSON
   System.out.println(hit.getSourceAsString());
}

 只需在构建查询请求体时增加分页相关属性即可。

④排序
// 创建搜索请求对象
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());
for (SearchHit hit : hits) {
    //输出每条查询的结果信息:转为JSON
    System.out.println(hit.getSourceAsString());
}

 只需在构建查询请求体时增加排序相关属性即可。

⑤过滤字段
// 创建搜索请求对象
SearchRequest request = new SearchRequest();
request.indices("user");
// 构建查询请求体
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
sourceBuilder.query(QueryBuilders.matchAllQuery());
// 过滤字段
String[] excludes = {};
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());
for (SearchHit hit : hits) {
    //输出每条查询的结果信息:转为JSON
    System.out.println(hit.getSourceAsString());
}
⑥bool查询
// 创建搜索请求对象
SearchRequest request = new SearchRequest();
request.indices("user");
// 构建查询请求体
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
boolQueryBuilder.must(QueryBuilders.matchQuery("age", 30));
boolQueryBuilder.mustNot(QueryBuilders.matchQuery("name", "zhangsan"));
boolQueryBuilder.should(QueryBuilders.matchQuery("sex", "男"));
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());
for (SearchHit hit : hits) {
    //输出每条查询的结果信息:转为JSON
    System.out.println(hit.getSourceAsString());
}

 需构建一个bool查询对象,适用于复杂条件查询。

⑦范围查询
// 创建搜索请求对象
SearchRequest request = new SearchRequest();
request.indices("user");
// 构建查询请求体
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
RangeQueryBuilder rangeQuery = QueryBuilders.rangeQuery("age");
rangeQuery.gte(30);
rangeQuery.lte(60);
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());
for (SearchHit hit : hits) {
    //输出每条查询的结果信息:转为JSON
    System.out.println(hit.getSourceAsString());
}
⑧模糊查询
// 创建搜索请求对象
SearchRequest request = new SearchRequest();
request.indices("user");
// 构建查询请求体
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
sourceBuilder.query(QueryBuilders.fuzzyQuery("name", "zhangsan").fuzziness(Fuzziness.ONE));
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());
for (SearchHit hit : hits) {
    //输出每条查询的结果信息:转为JSON
    System.out.println(hit.getSourceAsString());
}
2、高亮查询
// 创建搜索请求对象
SearchRequest request = new SearchRequest();
request.indices("user");
// 构建查询请求体
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
sourceBuilder.query(QueryBuilders.fuzzyQuery("name", "zhangsan").fuzziness(Fuzziness.ONE));
// 构建高亮字段
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());
for (SearchHit hit : hits) {
    //输出每条查询的结果信息:转为JSON
    System.out.println(hit.getSourceAsString());
    // 打印高亮结果
    System.out.println(hit.getHighlightFields());
}

 在原有查询的基础上再构建一个高亮查询对象,最后可以通过hit获取到高亮字段。

3、聚合查询
①最大年龄
// 创建搜索请求对象
SearchRequest request = new SearchRequest();
request.indices("user");
// 构建查询请求体
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
sourceBuilder.query(QueryBuilders.fuzzyQuery("name", "zhangsan").fuzziness(Fuzziness.ONE));
// 聚合字段
sourceBuilder.aggregation(AggregationBuilders.max("maxAge").field("age"));
request.source(sourceBuilder);
// 查询
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
System.out.println(response);

 构建查询请求体时增加聚合字段信息。

②分组统计
// 创建搜索请求对象
SearchRequest request = new SearchRequest();
request.indices("user");
// 构建查询请求体
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
sourceBuilder.query(QueryBuilders.fuzzyQuery("name", "zhangsan").fuzziness(Fuzziness.ONE));
sourceBuilder.aggregation(AggregationBuilders.terms("aggGroup").field("age"));
sourceBuilder.size(0);// size设置为0可以避免响应结果中原始数据的干扰
request.source(sourceBuilder);
// 查询
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
System.out.println(response);
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值