Elasticsearch Java High-Level REST Client 入门教程

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值