Skip to main content
 首页 » 编程设计

Elasticsearch Java High-Level REST Client 入门教程

2022年07月19日147myhome

Elasticsearch Java High-Level REST Client 入门教程

Elasticsearch是开源可扩展的全文检索和分析引擎,用于实时存储、搜索、分析海量信息。Java REST client是其官方提供的客户端,提供特定方法API并对请求和响应封装。本文聚焦如何使用High-Level REST Client。

1 环境准备

1.1 依赖

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' 

1.2 初始化RestHighLevelClient

@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应用较多。

2 API示例

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; 
    } 
} 

2.1 插入文档

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); 
    } 
 

2.2 查询文档

    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。

2.3 聚集查询

假如要实现下面查询:

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都不一样,输出结果正确。

3 总结

本文简单介绍了Elasticsearch Java High-Level REST Client应用,通过示例展示了如何插入、查询和分析文档,更多内容可以参考官方文档。


本文参考链接:https://blog.csdn.net/neweastsun/article/details/102728874
阅读延展