是否可以通过Elasticsearch聚合的键对结果进行分组?

时间:2014-08-08 21:37:19

标签: java elasticsearch

我正在尝试执行Elasticsearch查询,并希望Elasticsearch为我分组结果,而不是让我的客户端代码手动执行。看看Elasticsearch documentation,看起来像我正在寻找的汇总聚合,但我找不到任何使用它的示例,或者输出看起来确定的样子这就是我想要的。

我的问题是:是否可以通过Elasticsearch中的密钥对文档进行分组?如果是这样,我如何以及在哪里可以找到有关如何操作的文档,使用查询DSL或(最好)Java API的Javadoc?

2 个答案:

答案 0 :(得分:8)

我猜你试图通过elasticsearch中的字段进行分组,你可以使用Terms aggregation.

来完成

以下是使用查询dsl,

的方法
POST _search 
{
   "aggs": {
      "genders": {
         "terms": {
            "field": "gender"
         },
         "aggs": {
            "top_tag_hits": {
               "top_hits": {
                  "_source": {
                     "include": [
                        "include_fields_name"
                     ]
                  },
                  "size": 100
               }
            }
         }
      }
   }
}

性别是文档中的字段, 它的反应可以是

{
    ...

    "aggregations" : {
        "genders" : {
            "buckets" : [
                {
                    "key" : "male",
                    "doc_count" : 10,
                    "tag_top_hits":{"hits":...}
                },
                {
                    "key" : "female",
                    "doc_count" : 10,
                    "tag_top_hits":{"hits":...}
                },
            ]
        }
    }
}

使用Java api,我为您的评论添加了tophits aggregation。 (但不在查询dsl中)

client.prepareSearch("index").setTypes("types").addAggregation(
                AggregationBuilders.terms("agg_name").field("gender").subAggregation(
                        AggregationBuilders.topHits("documents").setSize(10)
                )
        ).execute(new ActionListener<SearchResponse>() {
            @Override
            public void onResponse(SearchResponse response) {
                Terms agg_name_aggregation=response.getAggregations().get("agg_name");
                for (Terms.Bucket bucket : agg_name_aggregation.getBuckets()) {
                    TopHits topHits=bucket.getAggregations().get("documents");
                    System.out.println("term = " + bucket.getKey());
                    // do what you want with top hits..
                }
            }

            @Override
            public void onFailure(Throwable e) {
                e.printStackTrace();
            }
        });

希望这会有所帮助!!

答案 1 :(得分:0)

使用汇总功能进行分组

    client.prepareSearch(indexName).setTypes(documentType).addAggregation
    (AggregationBuilders.terms("agg_name").field("gender").subAggregation(
    AggregationBuilders.topHits("documents").setSize(10))).execute(new ActionListener<SearchResponse>()
    {
        public void onResponse(SearchResponse response)
        {

            Terms agg_name_aggregation=response.getAggregations().get("agg_name");


            for (Terms.Bucket bucket : agg_name_aggregation.getBuckets())
            {
                TopHits topHits=bucket.getAggregations().get("documents");

                SearchResponse response1 = client
                        .prepareSearch(indexName)

                        .setQuery(QueryBuilders.termQuery("gender",bucket.getKey()))
                        .addAggregation(
                                AggregationBuilders.max("salary").field(
                                        "salary")).execute().actionGet();

                for (Aggregation avgAggs : response1.getAggregations())
                {
                    Max avg = (Max) avgAggs;

                    double maxValue = avg.getValue();

                    System.out.println("Avg Value => " + maxValue);
                }


             //   System.out.println("term = " + bucket.getKey());

             //   System.out.println("count =" + bucket.getDocCount());

              //  System.out.println(topHits.getHits());


                for (SearchHit hit: topHits.getHits())
                {

                    System.out.println(hit.getSource());
                }

            }

        }
        public void onFailure(Throwable e) {
            e.printStackTrace();
        }
    });
}