1. 程式人生 > >使用Java實現Elasticsearch的分組功能

使用Java實現Elasticsearch的分組功能

使用ES版本:1.7

ES上有如下資料

如果想根據class對student進行分組

GET school/student/_search?search_type=count
{
"aggs": {
  "class": {
    "terms": {
      "field": "class",
      "size": 100
    }
  }
 }
搜尋結果:

結果被放入到buckets中,key=1表示class的值為1(對class進行分組),doc_count為class=1的文件數,如果想用java程式碼實現此功能呢?

1.建立帶分組的搜尋方法

public class ElasticsearchUtils {

    private Client client;

    public ElasticsearchUtils(String clusterName, String ipAddress) {
        Settings settings = ImmutableSettings
                .settingsBuilder()
                //設定叢集名稱 
                .put("cluster.name", clusterName)
                .put("client.transport.ignore_cluster_name", false)
                .put("node.client", true).put("client.transport.sniff", true)
                .build();
        client = new TransportClient(settings)
                .addTransportAddress(new InetSocketTransportAddress(ipAddress,
                        9300));

/**
     * 執行搜尋(帶分組)
     * @param indexName 索引名稱
     * @param typeName 型別名稱
     * @param queryBuilder 查詢內容
     * @param aggsField 要分組的欄位
     * @return
     */
    public Map<String, String> searcher(String indexName, String typeName,
            QueryBuilder queryBuilder, String aggsField) {
        SearchRequestBuilder searchRequestBuilder = client
                .prepareSearch(indexName).setTypes(typeName)
                .setQuery(queryBuilder);
        //建立TermsBuilder物件,使用term查詢,設定該分組的名稱為aggs-class,並根據aggsField欄位進行分組
        TermsBuilder termsBuilder = AggregationBuilders.terms("aggs-class")
                .field(aggsField);//此處也可繼續設定order、size等
        //新增分組資訊
        searchRequestBuilder.addAggregation(termsBuilder);
        //執行搜尋
        SearchResponse searchResponse = searchRequestBuilder.execute()
                .actionGet();
        //解析返回資料,獲取分組名稱為aggs-class的資料
        Terms terms = searchResponse.getAggregations().get("aggs-class");
        Collection<Terms.Bucket> buckets = terms.getBuckets();
        Map<String, String> dataMap = new HashMap<String, String>();
        for (Terms.Bucket bucket : buckets) {
            String key = bucket.getKey();
            dataMap.put(key, bucket.getDocCount() + "");
        }
        return dataMap;
    }
 }

2.main函式
public class AggregationTest {
    public static void main(String[] args) {
        //建立物件,設定叢集名稱和IP地址
        ElasticsearchUtils es = new ElasticsearchUtils("im_shanmenglu",
                "localhost");
        String indexName = "school";//索引名稱
        String typeName = "student";//型別名稱
        String aggsField = "class";//要分組的欄位
        //分組搜尋
        Map<String, String> dataMap = es.searcher(indexName, typeName, null,
            aggsField);
        //解析結果
        for (Map.Entry<String, String> entry : dataMap.entrySet()) {

            System.out.println("class = " + entry.getKey() + ", Value = "
                    + entry.getValue());

        }
        //輸出class = 2, Value = 2(class=2的資料有2條)
        //   class = 1, Value = 5(class=1的資料有5條)

    }
}