使用Java實現Elasticsearch的分組功能
阿新 • • 發佈:2019-01-24
使用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條) } }