【问题标题】:Find unique field values in ElasticSearch using Spring Data ElasticsearchRepository使用 Spring Data ElasticsearchRepository 在 ElasticSearch 中查找唯一字段值
【发布时间】:2020-08-08 08:49:23
【问题描述】:

我有一个扩展 ElasticsearchRepository 的接口,并成功创建了搜索方法,例如:

Page<AuditResult> findByCustomerCodeAndHost(String customerCode, String host, Pageable pageable);

现在,我想要一个端点,它将返回该 customerCode 的所有可能的主机值,以便我可以在前端构建一个下拉列表来选择要发送到该 findByCustomerCodeAndHost 端点的值,例如:

List<String> findUniqueHostByCustomerCode(String customerCode)

这甚至可以使用 ElasticsearchRepository 实现吗?

我知道我可以使用 Distinct 关键字 List<String> findDistinctByCustomerCode(String customerCode); 但这不允许我指定主机字段。


编辑: 以下是我完成我想要的事情的方法,但由于目前无法使用 ElasticsearchRepository 实际执行此操作,因此它不是真正的“答案”。

我创建了一个 Spring web @RestController 类,我公开了一个执行聚合查询的 @GetMapping REST 端点。

kibana 控制台中的查询:

GET auditresult/_search
{
  "size": "0",
  "aggs" : {
    "uniq_custCode" : {
      "terms" : { "field" : "customerCode", "include": "<CUSTOMER_CODE>" },
        "aggs" : {
          "uniq_host" : {
           "terms" : { "field" : "host"}
          }
        }
      }
    }
  }

并且,基于这个问题ElasticSearch aggregation with Java 我想出了

@GetMapping("/hosts/{customerCode}")
String getHostsByCustomer(@PathVariable String customerCode) {
    SearchRequest searchRequest = new SearchRequest("auditresult");
    SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder().size(0);
    IncludeExclude ie = new IncludeExclude(customerCode, "");
    TermsAggregationBuilder aggregation =
            AggregationBuilders
                    .terms("uniq_custCode").includeExclude(ie)
                    .field("customerCode")
                    .subAggregation(
                            AggregationBuilders
                                    .terms("uniq_host")
                                    .field("host")
                    );
    searchSourceBuilder.aggregation(aggregation);
    searchRequest.source(searchSourceBuilder);
    try {
        SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
        Terms cust = searchResponse.getAggregations().get("uniq_custCode");
        StringBuilder sb = new StringBuilder();
        sb.append("{\"hosts\":[");
        for (Terms.Bucket bucket : cust.getBuckets()) {
            Terms hosts = bucket.getAggregations().get("uniq_hosts");
            for (Terms.Bucket host : hosts.getBuckets()) {
                System.out.println(host.getKey());
                sb.append("\"" + host.getKey() + "\",");
            }
        }
        String out = sb.toString();
        out = out.substring(0, out.length() - 1);
        return out + "]}";
    } catch (IOException e) {
        e.printStackTrace();
        return "{\"hosts\":[]}";
    }
}

【问题讨论】:

    标签: java rest elasticsearch spring-data-elasticsearch


    【解决方案1】:

    你需要的是 Spring Data 调用的投影,对于 Spring Data MongoDB,你可以read the documentation 看看它是如何工作的。

    唉,这在 Spring Data Elasticsearch 中还没有实现,我为此创建了an issue in Jira

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-07
      • 2020-04-24
      • 2018-12-29
      • 2020-09-22
      相关资源
      最近更新 更多