java - 使用java api在elasticsearch中按结果获取多个字段组

标签 java spring elasticsearch

我有一个 json

{"id": 2,"name": "Chethan","address":"Banglore"}

尝试对两个字段 id 和 name 进行分组,

List<String> statFields = new ArrayList();
        statFields.add("name");
        statFields.add("id");

        // 2. bootstrap the query
        SearchRequestBuilder search = client.prepareSearch("student")
            .setSize(0).setFrom(0)
            .setQuery(QueryBuilders.matchAllQuery());

        // 3. add a stats aggregation for each of your fields
        for (String field : statFields) {
            search.addAggregation(AggregationBuilders.terms(field+"_stats").field(field));
        }

        // 4. execute the query
        SearchResponse response = search.execute().actionGet();

        for(String field : statFields) {
        Terms termAgg = (Terms) response.getAggregations().get(field+"_stats");

        for (Terms.Bucket entry : termAgg.getBuckets()) {
            System.out.println(entry.getKey() + " **** " + entry.getDocCount()); // Doc count
        }
        }

以下是回复

chethan**** 2
Raj**** 1
Mohan**** 1
1 **** 1
2 **** 1
3 **** 1

但是我需要像sql这样的组合响应,

name    id     count
chethan 1         1

是否可以通过elasticsearch java api实现

最佳答案

您应该使用 subAggregation 并使用 keyword 类型进行聚合。

Java Rest High-Level Client

假设您的映射如下所示:

PUT student
{
  "mappings": {
    "doc": {
      "properties": {
        "name": {
          "type": "text",
          "fields": {
            "keyword": {
              "type": "keyword"
            }
          }
        },
        "id": {
          "type": "keyword"
        },
        "address": {
          "type": "text",
          "fields": {
            "keyword": {
              "type": "keyword"
            }
          }
        }
      }
    }
  }
}

为了分组名称id,您应该使用此查询(低级查询):

GET student/_search
{
  "size": 0,
  "aggs": {
    "name": {
      "terms": {
        "field": "name.keyword",
        "size": 10
      },"aggs": {
        "id": {
          "terms": {
            "field": "id",
            "size": 10
          }
        }
      }
    }
  }
}

在 java 中,上面的查询类似于:

SearchResponse response = client.search(new SearchRequest("student")
    .source(new SearchSourceBuilder()
            .size(0)
            .aggregation(
                    AggregationBuilders.terms("by_name").field("name.keyword")
                            .subAggregation(AggregationBuilders.terms("by_id")
                                    .field("id")
                            )
            );

如果你想使用你的代码,可能是这样的:

// 2. bootstrap the query
SearchRequestBuilder search = client.prepareSearch("student")
    .setSize(0).setFrom(0)
    .setQuery(QueryBuilders.matchAllQuery());

// 3. add a stats aggregation for each of your fields

TermsAggregationBuilder aggregation = AggregationBuilders.terms("name_stats").field("name.keyword");
aggregation.subAggregation(AggregationBuilders.terms("id_stats").field("id"));  
search.aggregation(aggregation);


// 4. execute the query
SearchResponse response = search.execute().actionGet();


    Terms termAgg = (Terms)response.getAggregations().get("name_stats");

    for (Terms.Bucket entry: termAgg.getBuckets()) {
        if (entry.getDocCount() != 0) {
            Terms terms =entry.getAggregations().get("id");
            Collection<Terms.Bucket> buckets = terms.getBuckets();
            for (Bucket sub : buckets ) {
                System.out.println((int) sub.getDocCount());
                System.out.println(sub.getKeyAsString());
            }
        }
    }

我删除了 for 循环。既然必须使用子聚合,您应该设计自己的结构。

更新

这是你想要的吗?

GET student/_search
{
  "size": 0, 
    "aggs" : {
        "name_id" : {
            "terms" : {
                "script" : {
                    "source": "doc['name.keyword'].value + '_' + doc['id'].value",
                    "lang": "painless"
                }
            }
        }
    }
}

我希望这就是您的目标。

关于java - 使用java api在elasticsearch中按结果获取多个字段组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58909061/

相关文章:

spring - 处理表单提交传递到 Spring MVC Controller 方法中的 "boolean"参数的最聪明方法是什么?

java - Spring Boot jsp文件未找到错误404奇怪的前缀

ruby - 如果与特定ID匹配,则提升Tire中查询的结果?

java - 在构造函数中创建内部类实例

java - java.lang.NullPointerException On按钮单击

java - 传递参数的不同方式 : String args[] or -D?

java - 以纯文本形式获取 XML

python - curl 请求以恢复 Elasticsearch 中的快照有效,但python中的相同请求不起作用

php - Elasticsearch 报错 No alive nodes found in your cluster

java - 按长属性对对象列表进行排序