如何使用Spring Data Elasticsearch(最新版本)和Spring Boot返回带有聚合的简单查询?

问题描述 投票:0回答:1

我正在尝试使用 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());

你知道为什么吗?

java spring spring-boot elasticsearch spring-data-elasticsearch
1个回答
0
投票

测试1:您只能在

StringQuery
中设置查询字符串,不能设置聚合,您需要使用
NativeQuery
来实现

测试 2:这是发送查询的正确方法,您应该在查询上将

maxResults
设置为 0,就像在直接 API 调用中所做的那样。您看不到聚合的原因是因为它作为返回的
SearchHits
对象的属性返回,而您的代码收集 matchall 查询返回的对象。

© www.soinside.com 2019 - 2024. All rights reserved.