在《ElasticSearch安装与Java Client API查询》中,介绍了简单查询的方法,下面介绍一些其他操作。
获取数量count
在ES查询时,SearchResponse中的SearchHits中包含有满足条件的记录数量;为了减少数据量的传递,查询时需要设定size为0,避免返回记录的详细信息,浪费时间与流量。
public long count(List<String> lstIndex, QueryBuilder queryBuilder) {
try (RestHighLevelClient client = getClient()) {
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
sourceBuilder.query(queryBuilder);
// sourceBuilder.from(0);
sourceBuilder.size(0);
sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
SearchRequest reqSearch = new SearchRequest(lstIndex.toArray(new String[0]));
reqSearch.source(sourceBuilder);
SearchResponse respSearch = client.search(reqSearch);
SearchHits hitsSearch = respSearch.getHits();
return hitsSearch.getTotalHits();
} catch (ElasticsearchStatusException ex) {
_logger.error("Count fail: {}", ex);
}
}
判断Index是否存在
ES7与ES6下判断的方式是不同的。
ES7中判断Index
在ES7下,可以方便地通过客户端连接的indices().exists来判断:
static boolean isIndexExists(String strIndex) {
try (RestHighLevelClient client = getRestHighLevelClient()) {
GetIndexRequest req = new GetIndexRequest(strIndex);
boolean resp = client.indices().exists(req, RequestOptions.DEFAULT);
System.out.println(strIndex + " exists: " + resp);
return resp;
} catch (Exception ex) {
ex.printStackTrace();
}
return false;
}
ES6中判断Index
ES6中无法使用上面的判断方法,只好通过BBossESStarter中的方法来实现。在yml中设定好ES相关配置后,即可通过@Autowired注解自动创建。
@Autowired
BBossESStarter bossStarter;
public boolean isIndexExists(String strIndex) {
ClientInterface client = bossStarter.getRestClient();
return client.existIndice(strIndex);
}
为了使用BBossESStarter,需要在pom中增加如下包:
<dependency>
<groupId>com.bbossgroups.plugins</groupId>
<artifactId>bboss-elasticsearch-rest-jdbc</artifactId>
<version>6.1.2</version>
<exclusions>
<exclusion>
<artifactId>slf4j-log4j12</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.bbossgroups.plugins</groupId>
<artifactId>bboss-elasticsearch-spring-boot-starter</artifactId>
<version>6.1.2</version>
<exclusions>
<exclusion>
<artifactId>slf4j-log4j12</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
</exclusions>
</dependency>
在yml文件中增加如下配置:
spring:
elasticsearch:
bboss:
# elasticUser: elastic
# elasticPassword: changeme
elasticsearch:
rest:
hostNames: 127.0.0.1:9200
##hostNames: 192.168.8.25:9200,192.168.8.26:9200,192.168.8.27:9200 ##集群地址配置
dateFormat: yyyy.MM.dd
timeZone: Asia/Shanghai
showTemplate: true
discoverHost: false
dslfile:
refreshInterval: -1
http:
timeoutConnection: 5000
timeoutSocket: 5000
connectionRequestTimeout: 5000
retryTime: 1
maxLineLength: -1
maxHeaderCount: 200
maxTotal: 400
defaultMaxPerRoute: 200
soReuseAddress: false
soKeepAlive: false
timeToLive: 3600000
keepAlive: 3600000
keystore:
keyPassword:
hostnameVerifier:
聚合(分组)查询
聚合提供了用户进行分组和数理统计的能力,可以把聚合理解成SQL中的GROUP BY和分组函数。
通过AggregationBuilder可以设定分组信息,分组结果在bucket中:
- 指标聚合:
max/min/avg/sum/stats
,获取分组中最大、最小、平均、和、统计值; - terms聚合:根据字段值项分组聚合;field按什么字段分组;size指定返回多少个分组;
- date_histogram聚合:时间直方图聚合(按天、月、年等进行聚合统计)可按 year (1y), quarter (1q), month (1M), week (1w), day (1d), hour (1h), minute (1m), second (1s) 间隔聚合或指定的时间间隔聚合;
static void groupTest() {
try (RestHighLevelClient client = getRestHighLevelClient()) {
List<String> lstIndex = new ArrayList<>();
lstIndex.add("stats-2020.11.03");
SearchRequest searchRequest = new SearchRequest(lstIndex.toArray(new String[0]));
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
sourceBuilder.size(0);
// AggregationBuilder agg = AggregationBuilders.sum("groups").field("count");
// AggregationBuilder agg = AggregationBuilders.terms("groups").field("count").size(100);
AggregationBuilder agg = AggregationBuilders.dateHistogram("groups")
.field("addDate")
.fixedInterval(DateHistogramInterval.MINUTE)
.minDocCount(1)
.order(BucketOrder.count(true));
sourceBuilder.aggregation(agg);
searchRequest.source(sourceBuilder);
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
MultiBucketsAggregation termNum = searchResponse.getAggregations().get("groups");
System.out.println("Agg Terms: " + termNum.getBuckets().size());
for (MultiBucketsAggregation.Bucket entry : termNum.getBuckets()) {
System.out.println("Agg: " + entry.getKeyAsString() + " - " + entry.getDocCount());
}
} catch (Exception ex) {
ex.printStackTrace();
}
}