赞
踩
Elasticsearch是开源可扩展的全文检索和分析引擎,用于实时存储、搜索、分析海量信息。Java REST client是其官方提供的客户端,提供特定方法API并对请求和响应封装。本文聚焦如何使用High-Level REST Client。
springboot 默认依赖的版本为6.8,这里在gradle.properties中指定版本7.3.0 。
elasticsearch.version=7.3.0
引用elasticsearch依赖。
implementation 'org.elasticsearch.client:elasticsearch-rest-high-level-client'
implementation 'org.elasticsearch.client:elasticsearch-rest-client'
implementation 'org.elasticsearch:elasticsearch'
@Configuration @Slf4j public class EsConfig { public static final String INDEX_NAME = "my_index"; @Value("192.168.0.1") private String elasticsearchHost; @Value("9200") private int port; @Bean(name = "highClient", destroyMethod = "close") public RestHighLevelClient client() { return new RestHighLevelClient(RestClient.builder(new HttpHost(elasticsearchHost,port)));; } @Bean public IndexRequest buildIndexRequest(){ return new IndexRequest(INDEX_NAME); } }
Spring boot也初始化了RestHighLevelClient,这里指定name为highClient。9200是发送http请求端口。
Java High-Level REST Client支持不同API,其中Index, Update, Search, Get, Delete, Bulk应用较多。
ElasticQuery类中引入client和indexRequest。同时定义SearchRequest infoSearch.
@Service
@Slf4j
public class ElasticQuery {
@Qualifier("highClient")
@Autowired
private RestHighLevelClient client;
private final IndexRequest indexRequest;
private SearchRequest infoSearch = new SearchRequest(INDEX_NAME);
public ElasticQuery(IndexRequest indexRequest) {
this.indexRequest = indexRequest;
}
}
IndexRequest提供重载方法source,支持不同类型的数据格式,下面示例使用Map。
public void insertDoc() throws IOException { Map<String,String> extInfo = Maps.newHashMap(); extInfo.put("name","李某"); extInfo.put("id_type","1"); extInfo.put("id_code","34561001"); extInfo.put("f_code","C04"); extInfo.put("s_code","01"); extInfo.put("res_property","02"); extInfo.put("person_id","100001"); extInfo.put("resource_key","210C04010001"); extInfo.put("flag","1"); indexRequest.id("80001").source(extInfo); client.index(indexRequest, RequestOptions.DEFAULT); }
public void queryDoc() throws IOException { SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); sourceBuilder.query(QueryBuilders.termQuery("name", "李某")); sourceBuilder.from(0); sourceBuilder.size(5); sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS)); infoSearch.source(sourceBuilder); SearchResponse response = client.search(infoSearch, RequestOptions.DEFAULT); long cnt = response.getHits().getTotalHits().value; log.info("result.hit={}", cnt); for (SearchHit hit : response.getHits()) { Map<String, Object> map = hit.getSourceAsMap(); log.info("map={}", map.toString()); log.info("docId={}", hit.getId()); } }
SearchSourceBuilder定义查询条件,from和size指定分页,timeout设置超时时间。SearchHit是查询结果,hit.getSourceAsMap()方法把查询结果转为Map。
假如要实现下面查询:
GET /nat_info_index/_search?size=0 { "query": { "bool": { "filter": {"term":{"flag":"1"}} } }, "aggs": { "f-cnt": { "terms": { "field": "f_code" }, "aggs": { "s-cnt": { "terms": { "field": "s_code" } } } } } }
查询所有flag为1的记录,然后根据f_code字段进行分组,在增加一个根据s_code自己进行子分组。
public void aggDoc() throws IOException { SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); searchSourceBuilder.size(0); // 增加bool过滤条件 BoolQueryBuilder booleanQuery = QueryBuilders.boolQuery().filter(QueryBuilders.termQuery("flag","1")); searchSourceBuilder.query(booleanQuery); // 增加聚集条件 AggregationBuilder aggregationBuilder = AggregationBuilders.terms("f-cnt").field("f_code").subAggregation( AggregationBuilders.terms("s-cnt").field("s_code") ); searchSourceBuilder.aggregation(aggregationBuilder); // 查询并解析查询结果 infoSearch.source(searchSourceBuilder); SearchResponse response = client.search(infoSearch.source(searchSourceBuilder), RequestOptions.DEFAULT); Terms ta1 = response.getAggregations().get("f-cnt"); List<? extends Terms.Bucket> hit1 = ta1.getBuckets(); for (Terms.Bucket bucket: hit1 ) { log.info("key={},cnt={}",bucket.getKey(), bucket.getDocCount()); Terms ta2 = bucket.getAggregations().get("s-cnt"); List<? extends Terms.Bucket> hit2 = ta2.getBuckets(); for (Terms.Bucket bucket2: hit2 ) { log.info("key2={}, cnt2={}", bucket2.getKey(), bucket2.getDocCount()); } } }
输出结果如下:
2019-10-24 18:07:08.712 INFO 5476 --- [ main] com.dataz.textsearch.query.ElasticQuery : key=C02,cnt=1
2019-10-24 18:07:08.713 INFO 5476 --- [ main] com.dataz.textsearch.query.ElasticQuery : key2=03, cnt2=1
2019-10-24 18:07:08.713 INFO 5476 --- [ main] com.dataz.textsearch.query.ElasticQuery : key=C04,cnt=1
2019-10-24 18:07:08.714 INFO 5476 --- [ main] com.dataz.textsearch.query.ElasticQuery : key2=01, cnt2=1
系统中仅有两条记录,且f_code和s_code都不一样,输出结果正确。
本文简单介绍了Elasticsearch Java High-Level REST Client应用,通过示例展示了如何插入、查询和分析文档,更多内容可以参考官方文档。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。