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 ...
随机推荐
- Android_Notification
xml文件: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns ...
- oracle学习总结5(游标、触发器、过程、方法)
1:捕获plsql抛出的异常 declarev_ename emp.ename%type;beginselect ename into v_ename from emp where empno=10; ...
- show variables 详解
back_log MySQL主线程检查连接并启动一个新线程这段时间内,可以设置多少个请求可以被存在堆栈中 connect_timeout 连接超时 检测方法nmap -p3306 数据库ip dela ...
- ASP.NET Web Froms开发模式中实现程序集的延迟加载
延迟加载是一个很大的诱惑,可以达到一些比较好的效果,比如: 1.在实体框架中,由于关联数据的数量和使用时机是不确定的,通过延迟加载,仅在使用的时候去执行关联数据的查询操作,减少无谓的数据查询操作,可以 ...
- 月下载量上千次的APP源码分享
在360上面上线了一个月,下载量上千余次.这里把代码都分享出来,供大家学习哈!还包括教大家如何接入广告,赚点小钱花花,喜欢的帮忙顶一个,大神见了勿喷,小学僧刚学Android没多久. 首先介绍这款应用 ...
- ionic+cordova+angularJs监听刷新
普通的js返回并刷新这里就不多说了,百度就有很多方法. 下面说的是使用了angularjs.ionic开发的一个手机app中我使用的返回上一页并刷新的方法. 场景:回复的页面是单独的,点击保存回复后会 ...
- HW—可怕的阶乘n!__注意大数据函数的使用BigInteger
java.math.BigInteger系列教程(四)BigInteger的诞生原因 为什么java里面要出现BigInteger类型呢?相信很多人有这个疑问,其实原因很简单,它可以表达更大范围的数值 ...
- JavaScript学习笔记(3)——JavaScript与HTML的组合方式
一.JavaScript可以写在HTML页面内部, 可位于 HTML 的 <body> 或 <head> 部分中,或者同时存在于两个部分中. 通常的做法是把函数放入 <h ...
- Eclipse Memory Analysis进行堆转储文件分析
生成堆转储文件 新建项目,设置Eclispe Java堆的大小: (1)限制Java堆大小:将最小值 -Xms参数与最大值-Xmx参数设置一样可避免堆的扩展 -Xmx20m -Xms2 ...
- VIM 拼写/spell check
VIM 拼写检查/spell check 一.Hunspell科普 Hunspell 作为一个拼写检查的工具,已经用在了许多开源的以及商业软件中.包括Google Chrome, Libreoffic ...