首先,我们需要造些数据,需要用到一个模型,这个模型定义了一个type,就算类型吧,我们用这个属性来演示常规的group。还有一个catIds的列表模型,这个来解决我们上面描述的一本书对应多个分类的需求。模型定义如下:
importjava.io.Serializable;
importjava.util.ArrayList;
importjava.util.List;
importjava.util.Random;
importcom.donlianli.es.ESUtils;
/**
* 这个是为分组定义的一个模型
* catIds通常为一对多的分类ID
* @authordonlian
*/
publicclassFacetTestModelimplementsSerializable {
privatestaticfinallongserialVersionUID = 31745778280079745L;
/**
* 随便编写的一些值,type属性只能取这里面的其中一个
*/
private String[] types= new String[]{
"type1,
"type11
};
//主ID
privatelong id;
//类型,为types之一
private String type;
/**
* 所属分类,范围为1-50
*/
private List publicFacetTestModel(){ Random r = newRandom(); int n =Math.abs(r.nextInt()); int index = n%14; this.type =types[index]; this.id =Math.abs(r.nextLong()); n = n%50; catIds= newArrayList catIds.add(n); intys = n%3; if(ys!=0){ for(int i=1;i } } } publicstaticvoid main(String[] argv){ for(int i=0;i<10;i++){ FacetTestModel f = newFacetTestModel(); System.out.println(ESUtils.toJson(f)); } } set,get方法,自己写吧 } 接着就是初始化数据。 importorg.elasticsearch.action.bulk.BulkRequestBuilder; importorg.elasticsearch.action.bulk.BulkResponse; importorg.elasticsearch.action.index.IndexRequestBuilder; importorg.elasticsearch.client.Client; importcom.donlianli.es.ESUtils; importcom.donlianli.es.model.FacetTestModel; publicclassBulkIndexTest { publicstaticvoid main(String[] args) { Client client=ESUtils.getClient(); BulkRequestBuilderbulkRequest=client.prepareBulk(); for(int i=0;i<10;i++){ String json= ESUtils.toJson(newFacetTestModel()); IndexRequestBuilderindexRequest= client.prepareIndex("test", "test") //指定不重复的ID .setSource(json).setId(String.valueOf(i)); //添加到builder中 bulkRequest.add(indexRequest); } BulkResponsebulkResponse=bulkRequest.execute().actionGet(); if (bulkResponse.hasFailures()) { System.out.println(bulkResponse.buildFailureMessage()); } } } 接下来,我们首先对type进行统计。在elasticsearch中,分组的功能叫facet,不知道为啥起这个名称。总之,就是对type的每一个值的数量进行统计,注意,要设置里面的size条件,否则默认只返回10个。 importorg.elasticsearch.action.search.SearchResponse; importorg.elasticsearch.client.Client; importorg.elasticsearch.index.query.FilterBuilders; importorg.elasticsearch.search.facet.FacetBuilders; importorg.elasticsearch.search.facet.Facets; importorg.elasticsearch.search.facet.terms.TermsFacet; importorg.elasticsearch.search.facet.terms.TermsFacetBuilder; importcom.donlianli.es.ESUtils; publicclassGroupTest { publicstaticvoid main(String[] argv){ Client client=ESUtils.getClient(); TermsFacetBuilderfacetBuilder= FacetBuilders.termsFacet("typeFacetName"); facetBuilder.field("type").size(Integer.MAX_VALUE); facetBuilder.facetFilter(FilterBuilders.matchAllFilter()); SearchResponse response = client.prepareSearch("test") .setTypes("test") .addFacet(facetBuilder) .setFilter(FilterBuilders.matchAllFilter()) .execute() .actionGet(); Facets f =response.facets(); //跟上面的名称一样 TermsFacet facet = (TermsFacet)f.getFacets().get("typeFacetName"); for(TermsFacet.Entrytf :facet.entries()){ System.out.println(tf.getTerm()+"\:\" +tf.getCount()); } client.close(); } } 运行程序后,大概得到如下结果: type3 : 4 type7 : 1 type6 : 1 type4 : 1 type13 :1 type12 :1 type11 :1 正好10个。初始化代码能对的上。 下面,我们就要对catIds进行统计了,再统计之前,我们先看看es里面都存储的是那些数据。 {id=36831749323317453, catIds=[4, 5], type=type3} {id=271209313870366004, catIds=[26, 27, 28], type=type3} {id=3486542174153835, catIds=[41, 42, 43], type=type4} {id=6826187683023110944, catIds=[46, 47], type=type7} {id=34375916617488747, catIds=[22, 23], type=type3} {id=6365837443081614150, catIds=[37, 38], type=type11} {id=2387331048448677498, catIds=[20, 21, 22], type=type3} {id=5595404824923951817, catIds=[31, 32], type=type13} {id=35937974463621044, catIds=[30], type=type12} {id=5824112111832084165, catIds=[1, 2], type=type6} 怎么对catIds进行统计呢,代码跟上面进行单个统计一样。 importorg.elasticsearch.action.search.SearchResponse; importorg.elasticsearch.client.Client; importorg.elasticsearch.index.query.FilterBuilders; importorg.elasticsearch.search.facet.FacetBuilders; importorg.elasticsearch.search.facet.Facets; importorg.elasticsearch.search.facet.terms.TermsFacet; importorg.elasticsearch.search.facet.terms.TermsFacetBuilder; importcom.donlianli.es.ESUtils; publicclass GroupTest2 { publicstaticvoid main(String[] argv){ Client client=ESUtils.getClient(); TermsFacetBuilderfacetBuilder= FacetBuilders.termsFacet("catIdName"); facetBuilder.field("catIds").size(Integer.MAX_VALUE); facetBuilder.facetFilter(FilterBuilders.matchAllFilter()); SearchResponse response = client.prepareSearch("test") .setTypes("test") .addFacet(facetBuilder) .setFilter(FilterBuilders.matchAllFilter()) .execute() .actionGet(); Facets f =response.facets(); //跟上面的名称一样 TermsFacet facet = (TermsFacet)f.getFacets().get("catIdName"); for(TermsFacet.Entrytf :facet.entries()){ System.out.println("键:"+tf.getTerm()+"\;数量:\" +tf.getCount()); } client.close(); } } 运行结果: 键:22 ;数量: 2 键:47 ;数量: 1 键:46 ;数量: 1 键:43 ;数量: 1 键:42 ;数量: 1 键:41 ;数量: 1 键:38 ;数量: 1 键:37 ;数量: 1 键:32 ;数量: 1 键:31 ;数量: 1 键:30 ;数量: 1 键:28 ;数量: 1 键:27 ;数量: 1 键:26 ;数量: 1 键:23 ;数量: 1 键:21 ;数量: 1 键:20 ;数量: 1 键:5 ;数量: 1 键:4 ;数量: 1 键:2 ;数量: 1 键:1 ;数量: 1 再和上面的数据对对,是不是除了22,其他的都是一个? 在分组这方面,ES真的很强大,除了上面的支持列表分组外,还支持范围分组rangeFacet,多个分组可以一次全部发送给ES等等,更多功能,大家还是自己多多验证。下载本文