我尝试使用Spring-Boot 3 + Spring Data ElasticSearch 5和Elasticsearch 8检索聚合品牌列表。
目前,我得到的结果,但从来没有汇总的。
我已经查阅了文档并在谷歌上搜索,但我找到的答案,我试图实现它们没有任何结论性的结果。
以下是我的三种方法:
使用Postman并返回聚合结果的基本查询:
{
"size": 0,
"aggs": {
"distinct_brand": {
"terms": {
"field": "brand",
"size": 10000,
"order": {
"_key": "asc"
}
}
}
}
}
测试1,使用StringQuery:
Query query = new StringQuery("{" +
" \"match_all\" : {}" +
" }," +
" \"size\": 100," +
" \"aggs\": {" +
" \"distinct_brand\": {" +
" \"terms\": {" +
" \"field\": \"brand\"," +
" \"size\": 10000," +
" \"order\": {" +
" \"_key\": \"asc\"" +
" }" +
" }" +
" }" +
" }");
SearchHits<Brand> searchHits = elasticsearchOperations.search(query, Brand.class);
List<Brand> brandList = searchHits.getSearchHits().stream()
.map(SearchHit::getContent)
.collect(Collectors.toList());
测试2,使用AggregationBuilders和withAggregation:
Aggregation aggregation = AggregationBuilders.terms(ta -> ta.field("brand").size(10000));
Query query = NativeQuery.builder()
.withQuery(q -> q.matchAll(ma -> ma))
.withAggregation("distinct_brand", aggregation)
.withPageable(PageRequest.of(0, 10000))
.build();
SearchHits<Brand> searchHits = elasticsearchOperations.search(query, Brand.class);
List<Brand> brandList = searchHits.getSearchHits().stream()
.map(SearchHit::getContent)
.collect(Collectors.toList());
测试3,使用JsonParser和SearchRequest:
JsonpMapper jsonpMapper = new JacksonJsonpMapper();
JsonParser jsonParser = Json.createParser(new StringReader("{" +
" \"match_all\" : {}" +
" }," +
" \"size\": 100," +
" \"aggs\": {" +
" \"distinct_brand\": {" +
" \"terms\": {" +
" \"field\": \"brand\"," +
" \"size\": 10000," +
" \"order\": {" +
" \"_key\": \"asc\"" +
" }" +
" }" +
" }" +
" }"));
SearchRequest request = SearchRequest._DESERIALIZER.deserialize(jsonParser, jsonpMapper);
NativeQueryBuilder nativeQueryBuilder = NativeQuery.builder();
for (Map.Entry<String, Aggregation> aggregationEntry : request.aggregations().entrySet()) {
nativeQueryBuilder.withAggregation(aggregationEntry.getKey(), aggregationEntry.getValue());
}
Query query = nativeQueryBuilder.withPageable(PageRequest.of(0, 10000)).build();
SearchHits<Brand> searchHits = elasticsearchOperations.search(query, Brand.class);
List<Brand> brandList = searchHits.getSearchHits().stream()
.map(SearchHit::getContent)
.collect(Collectors.toList());
你知道为什么吗?
2条答案
按热度按时间kkbh8khc1#
测试1:只能在
StringQuery
中设置查询字符串,不能在聚合中设置,需要使用NativeQuery
测试2:这是发送查询的正确方法,您应该在查询中将
maxResults
设置为0,就像您在直接API调用中所做的那样。您看不到聚合的原因是因为它是作为返回的SearchHits
对象的属性返回的,而您的代码收集matchall查询返回的对象。cx6n0qe32#
我是这样得到聚合的: