Elasticsearch Java High-Level REST Client 入门教程

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/neweastsun/article/details/102728874

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应用,通过示例展示了如何插入、查询和分析文档,更多内容可以参考官方文档。

猜你喜欢

转载自blog.csdn.net/neweastsun/article/details/102728874