ES去重查询
方式一(性能更好)
注意事项:
1、折叠功能ES5.3版本之后才发布的。
2、聚合&折叠只能针对keyword类型和number类型有效
POST /qt_config_device/_search
{
"query": {
"term": {
"tenantId": 554
}
},
"_source": "", // 过滤无关内容
"collapse": {
"field": "vendorName.keyword"
},
"size": 3,
"aggs": {
"vendor_count": { // 查询总数
"cardinality": {
"field": "vendorName.keyword"
}
}
}
}
对应的java实现
/**
* 折叠的实现方式,性能更好
* @param fuzzySearchPO
* @return
* @throws IOException
*/
private List<String> searchVendorV2(FuzzySearchPO fuzzySearchPO) throws IOException {
Long tenantId = Long.valueOf(UserContext.currentUser().getTenantId());
SearchRequest request = new SearchRequest(EsDb.qt_device.getValue());
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
sourceBuilder.fetchSource(false);
BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
boolQueryBuilder.must(QueryBuilders.termQuery("tenantId", tenantId));
if (StringUtils.isNotBlank(fuzzySearchPO.getKey())) {
boolQueryBuilder.must(QueryBuilders.wildcardQuery("vendorName.keyword", "*" + fuzzySearchPO.getKey() + "*"));
}
sourceBuilder.query(boolQueryBuilder);
//指定去重字段
CollapseBuilder collapseBuilder = new CollapseBuilder("vendorName.keyword");
sourceBuilder.collapse(collapseBuilder);
sourceBuilder.size(Optional.ofNullable(fuzzySearchPO.getSize()).orElse(10));
log.info("es查询语句:{}", sourceBuilder.toString());
request.source(sourceBuilder);
SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
SearchHit[] hits = response.getHits().getHits();
List<String> vendorNames = Arrays.stream(hits).map(h -> h.getFields().get("vendorName.keyword").getValues().get(0).toString()).collect(Collectors.toList());
return vendorNames;
}
方式二
POST /qt_config_device/_search
{
"query": {
"term": {
"tenantId": 554
}
},
"size": 0, // 过滤无关内容
"timeout": "60s",
"aggs": {
"vendor_terms": {
"terms": {
"field": "vendorName.keyword",
"size": 3
}
}
}
}
对应的java实现
/**
* 存储桶的实现方式
* @param fuzzySearchPO
* @return
* @throws IOException
*/
private List<String> searchVendorV1(FuzzySearchPO fuzzySearchPO) throws IOException {
Long tenantId = Long.valueOf(UserContext.currentUser().getTenantId());
SearchRequest request = new SearchRequest(EsDb.qt_device.getValue());
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
boolQueryBuilder.must(QueryBuilders.termQuery("tenantId", tenantId));
if (StringUtils.isNotBlank(fuzzySearchPO.getKey())) {
boolQueryBuilder.must(QueryBuilders.wildcardQuery("vendorName.keyword", "*" + fuzzySearchPO.getKey() + "*"));
}
sourceBuilder.query(boolQueryBuilder);
TermsAggregationBuilder terms = AggregationBuilders.terms("vendor_terms").field("vendorName.keyword").size(Optional.ofNullable(fuzzySearchPO.getSize()).orElse(10));
sourceBuilder.aggregation(terms);
sourceBuilder.size(0);
log.info("es查询语句:{}", sourceBuilder.toString());
request.source(sourceBuilder);
SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
ParsedTerms terms1 = (ParsedTerms) response.getAggregations().getAsMap().get("vendor_terms");
List<ParsedTerms.ParsedBucket> buckets = (List<ParsedTerms.ParsedBucket>) terms1.getBuckets();
List<String> vendorNames = buckets.stream().map(ParsedMultiBucketAggregation.ParsedBucket::getKeyAsString).collect(Collectors.toList());
return vendorNames;
}