springdata elasticsearch aggregation 操作

来源:互联网 发布:模拟视频信号传输网络 编辑:程序博客网 时间:2024/05/21 19:41

这段日子在搞 springdata 操作 elasticsearch 其中使用聚合操作,特此一记:

下面是https://github.com/spring-projects/spring-data-elasticsearch/tree/5.x 的spring-data-elasticsearch 项目的:ElasticsearchTemplateAggregationTests代码:


@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration("classpath:elasticsearch-template-test.xml")public class ElasticsearchTemplateAggregationTests {public static final String RIZWAN_IDREES = "Rizwan Idrees";public static final String MOHSIN_HUSEN = "Mohsin Husen";public static final String JONATHAN_YAN = "Jonathan Yan";public static final String ARTUR_KONCZAK = "Artur Konczak";public static final int YEAR_2002 = 2002;public static final int YEAR_2001 = 2001;public static final int YEAR_2000 = 2000;@Autowiredprivate ElasticsearchTemplate elasticsearchTemplate;@Beforepublic void before() {elasticsearchTemplate.deleteIndex(ArticleEntity.class);elasticsearchTemplate.createIndex(ArticleEntity.class);elasticsearchTemplate.putMapping(ArticleEntity.class);elasticsearchTemplate.refresh(ArticleEntity.class);IndexQuery article1 = new ArticleEntityBuilder("1").title("article four").subject("computing").addAuthor(RIZWAN_IDREES).addAuthor(ARTUR_KONCZAK).addAuthor(MOHSIN_HUSEN).addAuthor(JONATHAN_YAN).score(10).buildIndex();IndexQuery article2 = new ArticleEntityBuilder("2").title("article three").subject("computing").addAuthor(RIZWAN_IDREES).addAuthor(ARTUR_KONCZAK).addAuthor(MOHSIN_HUSEN).addPublishedYear(YEAR_2000).score(20).buildIndex();IndexQuery article3 = new ArticleEntityBuilder("3").title("article two").subject("computing").addAuthor(RIZWAN_IDREES).addAuthor(ARTUR_KONCZAK).addPublishedYear(YEAR_2001).addPublishedYear(YEAR_2000).score(30).buildIndex();IndexQuery article4 = new ArticleEntityBuilder("4").title("article one").subject("accounting").addAuthor(RIZWAN_IDREES).addPublishedYear(YEAR_2002).addPublishedYear(YEAR_2001).addPublishedYear(YEAR_2000).score(40).buildIndex();elasticsearchTemplate.index(article1);elasticsearchTemplate.index(article2);elasticsearchTemplate.index(article3);elasticsearchTemplate.index(article4);elasticsearchTemplate.refresh(ArticleEntity.class);}@Testpublic void shouldReturnAggregatedResponseForGivenSearchQuery() {// givenSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).withSearchType(SearchType.DEFAULT).withIndices("test-index-articles").withTypes("article").addAggregation(terms("subjects").field("subject")).build();// whenAggregations aggregations = elasticsearchTemplate.query(searchQuery, new ResultsExtractor<Aggregations>() {@Overridepublic Aggregations extract(SearchResponse response) {return response.getAggregations();}});// 
// Aggregations 只是获得了结果,没有取出数据;以及这样的实例;
assertThat(aggregations, is(notNullValue())); assertThat(aggregations.asMap().get("subjects"), is(notNullValue()));}}

其实上面代码使用 restful 方式的拼写为:

GET test-index-articles/article/_search{  "size": 0,   "aggs": {    "my_aggs_hehe": {      "terms": {        "field": "subject"      }    }  }}
以及返回的结果:

{  "took": 231,  "timed_out": false,  "_shards": {    "total": 1,    "successful": 1,    "failed": 0  },  "hits": {    "total": 4,    "max_score": 0,    "hits": []  },  "aggregations": {    "my_aggs_hehe": {      "doc_count_error_upper_bound": 0,      "sum_other_doc_count": 0,      "buckets": [        {          "key": "computing",          "doc_count": 3        },        {          "key": "accounting",          "doc_count": 1        }      ]    }  }}



那么我经过使用 java 的 debug 模式查看生成的类:



于是我将代码写如下:


@Testpublic void shouldReturnAggregatedResponseForGivenSearchQuery() {// givenSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).withSearchType(SearchType.DEFAULT).withIndices("test-index-articles").withTypes("article").addAggregation(terms("subjects").field("subject")).build();// whenAggregations aggregations = elasticsearchTemplate.query(searchQuery, new ResultsExtractor<Aggregations>() {@Overridepublic Aggregations extract(SearchResponse response) {return response.getAggregations();}});Map<String, Aggregation> map=aggregations.asMap();for(String s:map.keySet()){StringTerms a=(StringTerms) map.get(s);List<Terms.Bucket> list=a.getBuckets();for(Terms.Bucket b:list){System.out.println("key is "+ b.getKeyAsString()+"---and value is "+ b.getDocCount());}}// thenassertThat(aggregations, is(notNullValue()));assertThat(aggregations.asMap().get("subjects"), is(notNullValue()));}

于是结果为:

key is computing---and value is 3key is accounting---and value is 1