Elasticsearch强大的聚合功能Facet
在常规数据库中,我们都知道有一个sql就是group,分组。如果主表只有对应的一个列记录的分组的ID,那么还好统计,比如说每本书book表,有一个分类catId,记录是属于哪一类的书,那么直接按照catId进行分组即可。可是在实际应用种,并非如此简单。一本书往往属于多个分类,比如:某本书既属于科技类书,又属于儿童类书,要求按照这两种条件进行筛选,都能筛选出来,如果要求按照分类进行统计数量,数据库怎么group?我们且抛开种种解决方案,来看看Elasticsearch里面对这种需求,是多么的容易统计。
首先,我们需要造些数据,需要用到一个模型,这个模型定义了一个type,就算类型吧,我们用这个属性来演示常规的group。还有一个catIds的列表模型,这个来解决我们上面描述的一本书对应多个分类的需求。模型定义如下:
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Random; import com.donlianli.es.ESUtils;
/**
* 这个是为分组定义的一个模型
* catIds通常为一对多的分类ID
* @author donlian
*/
public class FacetTestModel implements Serializable {
private static final long serialVersionUID = 3174577828007649745L;
/**
* 随便编写的一些值,type属性只能取这里面的其中一个
*/
private String[] types= new String[]{
"type1","type2","type3","type4","type5","type6","type7",
"type11","type12","type13","type14","type15","type16","type17"
};
//主ID
private long id;
//类型,为types之一
private String type;
/**
* 所属分类,范围为1-50
*/
private List<Integer> catIds; public FacetTestModel(){
Random r = new Random();
int n = Math.abs(r.nextInt());
int index = n%14;
this.type = types[index];
this.id = Math.abs(r.nextLong()); n = n%50;
catIds = new ArrayList<Integer>();
catIds.add(n);
int ys = n%3;
if(ys!=0){
for(int i=1;i<ys+1;i++){
catIds.add(n+i);
}
}
}
public static void main(String[] argv){
for(int i=0;i<10;i++){
FacetTestModel f = new FacetTestModel();
System.out.println(ESUtils.toJson(f));
}
}
set,get方法,自己写吧
}
接着就是初始化数据。
import org.elasticsearch.action.bulk.BulkRequestBuilder;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.index.IndexRequestBuilder;
import org.elasticsearch.client.Client; import com.donlianli.es.ESUtils;
import com.donlianli.es.model.FacetTestModel; public class BulkIndexTest { public static void main(String[] args) {
Client client = ESUtils.getClient();
BulkRequestBuilder bulkRequest = client.prepareBulk();
for(int i=0;i<10;i++){
String json = ESUtils.toJson(new FacetTestModel());
IndexRequestBuilder indexRequest = client.prepareIndex("test", "test")
//指定不重复的ID
.setSource(json).setId(String.valueOf(i));
//添加到builder中
bulkRequest.add(indexRequest);
} BulkResponse bulkResponse = bulkRequest.execute().actionGet();
if (bulkResponse.hasFailures()) {
System.out.println(bulkResponse.buildFailureMessage());
}
}
}
接下来,我们首先对type进行统计。在elasticsearch中,分组的功能叫facet,不知道为啥起这个名称。总之,就是对type的每一个值的数量进行统计,注意,要设置里面的size条件,否则默认只返回10个。
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.Client;
import org.elasticsearch.index.query.FilterBuilders;
import org.elasticsearch.search.facet.FacetBuilders;
import org.elasticsearch.search.facet.Facets;
import org.elasticsearch.search.facet.terms.TermsFacet;
import org.elasticsearch.search.facet.terms.TermsFacetBuilder; import com.donlianli.es.ESUtils; public class GroupTest {
public static void main(String[] argv){
Client client = ESUtils.getClient();
TermsFacetBuilder facetBuilder = 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.Entry tf :facet.entries()){
System.out.println(tf.getTerm()+"\t:\t" + tf.getCount());
}
client.close();
}
}
运行程序后,大概得到如下结果:
type3 : 4
type7 : 1
type6 : 1
type4 : 1
type13 : 1
type12 : 1
type11 : 1
正好10个。初始化代码能对的上。
下面,我们就要对catIds进行统计了,再统计之前,我们先看看es里面都存储的是那些数据。
{id=3683174899323317453, catIds=[4, 5], type=type3}
{id=271209313870366004, catIds=[26, 27, 28], type=type3}
{id=348654892174153835, catIds=[41, 42, 43], type=type4}
{id=6826187683023110944, catIds=[46, 47], type=type7}
{id=3437591661789488747, 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=3593797446463621044, catIds=[30], type=type12}
{id=5824112111832084165, catIds=[1, 2], type=type6}
怎么对catIds进行统计呢,代码跟上面进行单个统计一样。
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.Client;
import org.elasticsearch.index.query.FilterBuilders;
import org.elasticsearch.search.facet.FacetBuilders;
import org.elasticsearch.search.facet.Facets;
import org.elasticsearch.search.facet.terms.TermsFacet;
import org.elasticsearch.search.facet.terms.TermsFacetBuilder; import com.donlianli.es.ESUtils; public class GroupTest2 {
public static void main(String[] argv){
Client client = ESUtils.getClient();
TermsFacetBuilder facetBuilder = 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.Entry tf :facet.entries()){
System.out.println("键:"+tf.getTerm()+"\t;数量:\t" + 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等等,更多功能,大家还是自己多多验证。

Elasticsearch强大的聚合功能Facet的更多相关文章
- SSRS 系列 - 使用带参数的 MDX 查询实现一个分组聚合功能的报表
SSRS 系列 - 使用带参数的 MDX 查询实现一个分组聚合功能的报表 SSRS 系列 - 使用带参数的 MDX 查询实现一个分组聚合功能的报表 2013-10-09 23:09 by BI Wor ...
- 点聚合功能---基于ARCGIS RUNTIME SDK FOR ANDROID
一直不更新博客的原因,如果一定要找一个,那就是忙,或者说懒癌犯了. 基于ArcGIS RunTime SDK for Android的点聚合功能,本来是我之前做过的一个系统里面的一个小部分,今天抽出一 ...
- MongoCola使用教程 1 - MongoDB的基本操作和聚合功能---Mongdb客户端软件操作说明
前言 在开始正文之前,感谢博客园的Nosql爱好者对于MongoCola工具的试用(使用).特别感谢 呆呆 这位朋友的Bug报告,让我纠正了一个很严重的Bug.同时也感谢以前的多个网友在博客留言中给我 ...
- jQuery Validate 插件为表单提供了强大的验证功能
之前项目开发中,表单校验用的jQuery Validate 插件,这个插件为表单提供了强大的验证功能,让客户端表单验证变得更简单,同时提供了大量的定制选项,满足应用程序各种需求.该插件捆绑了一套有用的 ...
- php图像处理(thinkphp框架有相对强大的图像处理功能)
php图像处理(thinkphp框架有相对强大的图像处理功能) 一.总结 1.php处理图像:php处理图像需要安装外库(gd库) 2.gd库函数可以非常完美的操作图像:安装好库之后,这个库里面的函数 ...
- 借助Mac自带的强大的搜索功能,如何快速搜索打开Tuxera Disk Manager
现在很多小伙伴们在遇到Mac读写NTFS格式硬盘问题的时候,都会选择使用Tuxera NTFS这个磁盘读写工具.因为这款读写工具不仅可以帮助我们进行读写工作,还具有一个磁盘管理工具Disk Manag ...
- 小试牛刀ElasticSearch大数据聚合统计
ElasticSearch相信有不少朋友都了解,即使没有了解过它那相信对ELK也有所认识E即是ElasticSearch.ElasticSearch最开始更多用于检索,作为一搜索的集群产品简单易用绝对 ...
- Django之强大的Form功能
转载: http://www.cnblogs.com/0820-zq/p/5807980.html Form Form的验证思路 前端:form表单 后台:创建form类,当请求到来时,先匹配,匹配出 ...
- java使用elasticsearch分组进行聚合查询(group by)-项目中实际应用
java连接elasticsearch 进行聚合查询进行相应操作 一:对单个字段进行分组求和 1.表结构图片: 根据任务id分组,分别统计出每个任务id下有多少个文字标题 .SQL:select id ...
随机推荐
- word-wrap,word-break,text-wrap的区别
今晚看到了无双老师关于word-wrap,word-break区别的讲解 http://www.cnblogs.com/2050/archive/2012/08/10/2632256.html 受益 ...
- appscan 安全漏洞修复办法
appscan 安全漏洞修复办法http://www.automationqa.com/forum.php?mod=viewthread&tid=3661&fromuid=21
- xampp 安装后无法启动apache 的解决方法
1,安装xampp 后,apache 无法启动,当时的报错已经没有证据了,大概的翻译就是端口 被block(锁定)的意思 2,通过 查找端口被占用,找到被占用程序,进行杀掉进程,或者卸载软件,参考网址 ...
- 搭建eclipse+maven+scala-ide的scala web开发环境
http://www.tuicool.com/articles/NBzAzy 江湖传闻,scala开发的最佳利器乃 JetBrains 的神作 IntelliJ IDEA ,外加构建工具sbt 是也. ...
- 阿里云 mysql 无缘无故挂掉
近期在登录自己博客时,老是报数据库连接失败,然后重启服务器就好了.但是,重启服务器很耗时间,不方便,不能每次都重启吧于是远程连接服务器看了一下原来是数据库服务挂掉了启动时还报错于是查看了下错误日志 2 ...
- smarty半小时快速上手入门教程
http://www.jb51.net/article/56754.htm http://www.yiibai.com/smarty/smarty_functions.html http://www. ...
- Java多线程概述
/*多线程1.首先说进程,进程---就是正在进行的程序 每一个进程都有一个执行程序.该顺序是一个执行路径,或者叫一个控制单元 2.线程:就是进程中的一个独立的进程单元 线程在控制着 ...
- C++实用数据结构:二叉索引树
看下面这个问题(动态连续和查询): 有一个数组A(长度为n),要求进行两种操作: add(i,x):让Ai增大x: query(a,b):询问Aa+Aa+1+...+Ab的和: 若进行模拟,则每次qu ...
- OpenJudge 2792 集合加法
1.链接地址: http://bailian.openjudge.cn/practice/2792 2.题目: 总Time Limit: 3000ms Memory Limit: 65536kB De ...
- OpenJudge/Poj 2027 No Brainer
1.链接地址: http://bailian.openjudge.cn/practice/2027 http://poj.org/problem?id=2027 2.题目: 总Time Limit: ...