- 浏览: 2182547 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (682)
- 软件思想 (7)
- Lucene(修真篇) (17)
- Lucene(仙界篇) (20)
- Lucene(神界篇) (11)
- Solr (48)
- Hadoop (77)
- Spark (38)
- Hbase (26)
- Hive (19)
- Pig (25)
- ELK (64)
- Zookeeper (12)
- JAVA (119)
- Linux (59)
- 多线程 (8)
- Nutch (5)
- JAVA EE (21)
- Oracle (7)
- Python (32)
- Xml (5)
- Gson (1)
- Cygwin (1)
- JavaScript (4)
- MySQL (9)
- Lucene/Solr(转) (5)
- 缓存 (2)
- Github/Git (1)
- 开源爬虫 (1)
- Hadoop运维 (7)
- shell命令 (9)
- 生活感悟 (42)
- shell编程 (23)
- Scala (11)
- MongoDB (3)
- docker (2)
- Nodejs (3)
- Neo4j (5)
- storm (3)
- opencv (1)
最新评论
-
qindongliang1922:
粟谷_sugu 写道不太理解“分词字段存储docvalue是没 ...
浅谈Lucene中的DocValues -
粟谷_sugu:
不太理解“分词字段存储docvalue是没有意义的”,这句话, ...
浅谈Lucene中的DocValues -
yin_bp:
高性能elasticsearch ORM开发库使用文档http ...
为什么说Elasticsearch搜索是近实时的? -
hackWang:
请问博主,有用solr做电商的搜索项目?
Solr中Group和Facet的用法 -
章司nana:
遇到的问题同楼上 为什么会返回null
Lucene4.3开发之第八步之渡劫初期(八)
最近有个日志收集监控的项目采用的技术栈是ELK+JAVA+Spring,客户端语言使用的是Java,以后有机会的话可以试一下JavaScript+Nodejs的方式,非常轻量级的组合,只不过不太适合服务化的工程,Kibana充当可视化层,功能虽然非常强大和灵活,但是需要业务人员懂Lucene的查询语法和Kibana的Dashboard仪表盘自定义功能才能玩的转,所以Kibana面向专业的开发人员和运维人员比较良好,但面向业务人员则稍微有点难度,我们这边就使用Java进行二次开发,然后前端定义几个业务人员关注的图表,然后把后端查询的数据,按照一定的维度放进去即可。
基础环境:
(1)ElasticSearch1.7.2
(2)Logstash2.2.2
(3)Kibana4.1.2
(3)JDK7
(4)Spring4.2
使用到的技术点:
(1)ElasticSearch的查询
(2)ElasticSearch的过滤
(3)ElasticSearch的日期聚合
(4)ElasticSearch的Terms聚合
(5)ElasticSearch的多级分组
(6)ElasticSearch+Logstash的时区问题
直接上代码:
package cn.bizbook.product.elk.dao.impl; import cn.bizbook.product.elk.config.ESConf; import cn.bizbook.product.elk.dao.ESDao; import cn.bizbook.product.elk.utils.TimeTools; import cn.bizbook.product.elk.vo.count.Condition; import cn.bizbook.product.elk.vo.count.CountType; import cn.bizbook.product.elk.vo.count.search.GroupCount; import cn.bizbook.product.elk.vo.count.search.MonitorCount; import org.apache.commons.lang.StringUtils; import org.apache.lucene.queryparser.classic.QueryParserBase; import org.elasticsearch.action.search.SearchRequestBuilder; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.client.Client; import org.elasticsearch.index.query.FilterBuilders; import org.elasticsearch.index.query.QueryBuilder; import org.elasticsearch.index.query.QueryBuilders; import org.elasticsearch.index.query.QueryStringQueryBuilder; import org.elasticsearch.search.aggregations.AggregationBuilders; import org.elasticsearch.search.aggregations.Aggregations; import org.elasticsearch.search.aggregations.bucket.histogram.DateHistogram; import org.elasticsearch.search.aggregations.bucket.histogram.DateHistogramBuilder; import org.elasticsearch.search.aggregations.bucket.histogram.Histogram; import org.elasticsearch.search.aggregations.bucket.terms.StringTerms; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Repository; import javax.annotation.Resource; import java.util.ArrayList; import java.util.List; /** * Created by qindongliang on 2016/4/6. */ @Repository("esDaoImpl") public class ESDaoImpl implements ESDao { private static Logger log= LoggerFactory.getLogger(ESDaoImpl.class); @Autowired private ESConf esConf; @Resource(name = "client") private Client client; @Override public MonitorCount count() { MonitorCount count=new MonitorCount(); //今天的数量 count.setToday_count(customCount(false,"*:*")); //今天的入库量 count.setToday_store_count(customCount(false,"-save:1")); //所有的总量 count.setTotal_count(customCount(true,"*:*")); //所有的入库总量 count.setTotal_store_count(customCount(true,"-save:1")); return count; } private long customCount(boolean isQueryAll, String queryString){ try { //今天的开始时间 比如2016-04-01 00:00:00 long today_start = TimeTools.getDayTimeStamp(0); //今天的结束时间 也就是明天的开始时间 比如2016-04-02 00:00:00 //一闭区间一开区间即得到一天的统计量 long today_end=TimeTools.getDayTimeStamp(1); StringBuffer fq = new StringBuffer(); fq.append("@timestamp:") .append(" [ ") .append(today_start) .append(" TO ") .append(today_end) .append(" } "); //构建查询请求,使用Lucene高级查询语法 QueryBuilder query=QueryBuilders.queryStringQuery(queryString); //构建查询请求 SearchRequestBuilder search = client.prepareSearch("crawl*").setTypes("logs"); //非所有的情况下,设置日期过滤 if(isQueryAll){ search.setQuery(query);//查询所有 }else {//加上日期过滤 search.setQuery(QueryBuilders.filteredQuery(query, FilterBuilders.queryFilter(QueryBuilders.queryStringQuery(fq.toString())))); } SearchResponse r = search.get();//得到查询结果 long hits = r.getHits().getTotalHits();//读取命中数量 return hits; }catch (Exception e){ log.error("统计日期数量出错!",e); } return 0; } @Override public List<GroupCount> query(Condition condition) { return grouyQuery(condition); } /*** * @param c 查询的条件 * @return 查询的结果 */ private List<GroupCount> grouyQuery(Condition c){ //封装结果集 List<GroupCount> datas=new ArrayList<>(); //组装分组 DateHistogramBuilder dateAgg = AggregationBuilders.dateHistogram("dateagg"); //定义分组的日期字段 dateAgg.field("@timestamp"); //按天分组 if(CountType.EACH_DAY==(c.getType())) { dateAgg.interval(DateHistogram.Interval.DAY); dateAgg.timeZone("+8:00"); dateAgg.format("yyyy-MM-dd"); //按小时分组 }else if(CountType.EACH_HOUR==c.getType()){ dateAgg.interval(DateHistogram.Interval.HOUR); //按小时分组,必须使用这个方法,不然得到的结果不正确 dateAgg.postZone("+8:00"); dateAgg.format("yyyy-MM-dd HH"); //无效分组 }else{ throw new NullPointerException("无效的枚举类型"); } //二级分组,统计入库的成功失败量 0 1 2 , 1为不成功 dateAgg.subAggregation(AggregationBuilders.terms("success").field("save")); //查询过滤条件 StringBuffer fq = new StringBuffer(); //过滤时间字段 fq.append(" +@timestamp:") .append(" [ ") .append(c.getStart().getTime()) .append(" TO ") .append(c.getEnd().getTime()) .append(" } "); //过滤一级 if(StringUtils.isNotEmpty(c.getT1())){ fq.append(" +t1:").append(c.getT1()); } //过滤二级 if(StringUtils.isNotEmpty(c.getT2())){ fq.append(" +t2:").append(c.getT2()); } //过滤三级 if(StringUtils.isNotEmpty(c.getT3())){ fq.append(" +t3:").append(c.getT3()); } //过滤url if(StringUtils.isNotEmpty(c.getSourceUrl())){ //对url进行转义,防止查询出现错误 fq.append(" +url:").append(QueryParserBase.escape(c.getSourceUrl())); } //过滤省份编码 if(StringUtils.isNotEmpty(c.getProvinceCode())){ fq.append(" +pcode:").append(c.getProvinceCode()); } //过滤入库状态 if(c.getSavaState()!=null){ fq.append(" +save:").append(c.getSavaState().getCode()); } //过滤http状态码 if(c.getWebsiteState()!=null){ if(!c.getWebsiteState().getCode().equals("-1")) { fq.append(" +httpcode:").append(c.getWebsiteState().getCode()); }else{ fq.append(" -httpcode:").append("(0 110 200)"); } } //过滤配置configid if(StringUtils.isNotEmpty(c.getConfigId())){ fq.append(" +cid:").append(c.getConfigId()); } //查询索引 SearchRequestBuilder search=client.prepareSearch("crawl*").setTypes("logs"); //组装请求 search.setQuery(QueryBuilders.filteredQuery(QueryBuilders.matchAllQuery(), FilterBuilders.queryFilter(QueryBuilders.queryStringQuery(fq.toString()) .defaultOperator(QueryStringQueryBuilder.Operator.AND) ))).addAggregation(dateAgg); //获取查询结果 SearchResponse r = search.get();//得到查询结果 //获取一级聚合数据 Histogram h=r.getAggregations().get("dateagg"); //得到一级聚合结果里面的分桶集合 List<DateHistogram.Bucket> buckets = (List<DateHistogram.Bucket>) h.getBuckets(); //遍历分桶集 for(DateHistogram.Bucket b:buckets){ //读取二级聚合数据集引用 Aggregations sub = b.getAggregations(); //获取二级聚合集合 StringTerms count = sub.get("success"); GroupCount groupCount=new GroupCount(); //设置x轴分组日期 groupCount.setGroupKey(b.getKey()); //设置指定分组条件下入库总量 groupCount.setTotal_count(b.getDocCount()); //读取指定分组条件下不成功的数量 long bad_count=count.getBucketByKey("1")==null?0:count.getBucketByKey("1").getDocCount(); //设置指定分组条件下成功的入库量 groupCount.setTotal_store_count(b.getDocCount()-bad_count); //计算成功率 groupCount.setSuccess_rate(groupCount.getTotal_store_count()*1.0/groupCount.getTotal_count()); //添加到集合里面 datas.add(groupCount); } return datas; } }
总结:
(1)关于时区的问题,目前发现在测试按小时,按天分组统计的时候,时区使用的方法不是一致的,而postZone这个方法,在1.5版本已经废弃,说是使用timeZone替代,但经测试发现在按小时分组的时候,使用timeZone加8个时区的并没生效,后续看下最新版本的ElasticSearch是否修复。
(2)使用Terms的聚合分组时,这个字段最好是没有分过词的,否则大量的元数据返回,有可能会发生OOM的异常
(3)在不需要评分排名查询的场景中,尽量使用filter查询,elasticsearch会缓存查询结果,从而能大幅提高检索性能
今天先总结这么多,后续有空再关注下
(1)elasticsearch中的Aggregations和Facet的区别以及对比Solr中的Group和Facet的区别
(2)在不同的聚合渠道中多级分组中是组内有序还是全局有序
有什么问题 可以扫码关注微信公众号:我是攻城师(woshigcs),在后台留言咨询。
本公众号的内容是有关搜索和大数据技术和互联网等方面内容的分享,也是一个温馨的技术互动交流的小家园
发表评论
-
复盘一个Elasticsearch排序问题的剖析
2019-07-15 21:12 1165最近线上的es查询的 ... -
elasticsearch里面bulk的用法
2018-04-09 20:23 1422上篇文章介绍了在es里 ... -
elasticsearch里面的关于批量读取mget的用法
2018-04-04 16:01 1832es的api除了提供了基本 ... -
elasticsearch的查询流程分析
2018-04-02 20:29 1327我们都知道es是一个分 ... -
如何在elasticsearch里面使用深度分页功能
2018-03-28 18:13 2019前面的文章提到过es默认的from+size的分页方式返回的结 ... -
如何在Elasticsearch里面使用索引别名
2018-03-27 20:37 1678在elasticsearch里面给index起一个alias ... -
如何优雅的全量读取Elasticsearch索引里面的数据
2018-03-26 20:27 7651### (一)scroll的介绍 有时候我们可能想要读取整个 ... -
关于elaticsearch中更新数据的几种方式
2018-03-21 19:00 965作为一个成熟的框架, ... -
Elasticsearch里面的segment合并
2018-03-20 17:50 2091通过前面的文章,我 ... -
Elasticsearch如何保证数据不丢失?
2018-03-19 20:52 2140上篇文章提到过,在elasticsearch和磁盘之间还有一层 ... -
为什么说Elasticsearch搜索是近实时的?
2018-03-16 19:41 9452通过前面两篇文章的介绍,我们大概已经知道了 Elasticse ... -
Elasticsearch如何动态维护一个不可变的倒排索引
2018-03-15 21:34 1136上一篇文章中介绍了Elasticsearch中是如何搜索文本 ... -
Elasticsearch如何检索数据
2018-03-14 20:11 1067我们都知道Elasticsearch是一个全文检索引擎,那么它 ... -
如何备份ElasticSearch索引数据到HDFS上
2018-02-09 18:19 2420在ElasticSearch里面备份策略已经比较成熟了 ... -
Elasticsearch5.6.4集群搭建
2018-02-07 20:13 1340本次搭建的是一个三节点的集群 (一)es的安装 (1)下 ... -
如何使log4j生成json格式的log
2017-09-15 17:44 3821使用java开发项目时,log日志一般都是应用程序必不可少的一 ... -
理解elasticsearch的parent-child关系
2017-09-04 18:43 2841前面文章介绍了,在es里面的几种数据组织关系,包括array ... -
简述ElasticSearch里面复杂关系数据的存储方式
2017-08-18 20:10 2414在传统的数据库里面,对数据关系描述无外乎三种,一对一,一对多和 ... -
使用Java Rest Client操作Elasticsearch
2017-08-09 19:42 2271Elasticsearch作为一个成熟的开源框架,对主流的多种 ... -
ElasticSearch里面的偏好查询
2017-06-22 17:17 1303在es查询的时候我们可 ...
相关推荐
**Elasticsearch Java API**是Elasticsearch与Java应用程序交互的主要工具,它允许开发者在Java环境中无缝地创建、管理和查询Elasticsearch索引。Elasticsearch是一个分布式、RESTful风格的搜索和数据分析引擎,用于...
在本项目实战中,我们将探讨如何使用Java编程语言,结合Spark和Hive,将Hive中的数据高效地导入到ElasticSearch(ES)中,并利用ES的别名机制实现数据更新的平滑过渡。以下是对这个流程的详细解析: 1. **Hive数据...
Elasticsearch提供了Java API,使得Java开发者可以直接在代码中操作Elasticsearch集群,执行索引、查询、更新和删除等操作。这个API是与Elasticsearch服务器通信的主要方式,简化了开发过程。 3. **安装与配置** ...
例如,你可能会看到如何使用Java API或者curl命令来与Elasticsearch交互,创建索引并插入文档,或者执行复杂的聚合查询。 在实战部分,你可能会学习到如何处理实时数据流,比如日志分析或者实时监控。Elasticsearch...
6 1.3.2 JSON介绍 10 1.4 安装配置 12 1.4.1 安装Java 12 1.4.2 安装Elasticsearch 12 1.4.3 配置 13 1.4.4 运行 15 1.4.5 停止 17 1.4.6 作为服务 17 1.4.7 版本升级 19 1.5 对外接口 21 1.5.1 API约定 22 1.5 .2 ...
Elasticsearch是一款开源的、分布式的全文搜索引擎,由Java编写,设计用于处理海量数据的快速检索。黄申翻译的《Elasticsearch实战》一书,深入浅出地介绍了Elasticsearch的核心概念、功能以及实际应用。书中附带的...
《Elasticsearch实战:基于Java的深度探索》 在当今大数据时代,Elasticsearch作为一款强大的开源全文搜索引擎,因其高效、灵活和可扩展性而备受青睐。本篇将围绕"elasticsearch-test.zip"这个压缩包文件,深入探讨...
《Java Elasticsearch实战》这本书主要探讨了如何利用Java API与Elasticsearch进行深度集成,从而实现高效的数据检索和分析。Elasticsearch是一个分布式、RESTful风格的搜索和数据分析引擎,广泛应用于日志分析、...
Java API是与Elasticsearch交互的主要方式之一,可以方便地创建索引、插入文档、执行查询等操作。 其次,**SpringBoot** 是Spring框架的一个简化版,它旨在简化创建独立的、生产级别的基于Spring的应用程序。通过...
s这门技术有点特殊,跟比如其他的像纯java的课程,比如分布式课程,或者大数据...《核心知识篇(下半季)》,包括深度讲解搜索这块技术,还有聚合分析这块技术,包括数据建模,包括java api的复杂使用,有一个项目实战s
【标题】"Lucene全文检索入门项目 Java实现Maven项目 Elasticsearch 基础实战" 提供了一个学习如何在Java环境中运用全文检索技术的起点。这个项目涵盖了两个主要的开源工具:Lucene和Elasticsearch,它们都是业界...
**Elasticsearch 6.8.0:核心概念与实战指南** Elasticsearch 是一个流行的开源全文搜索引擎,基于 Lucene 库,广泛用于实时数据分析、日志聚合、搜索和信息检索。版本 6.8.0 提供了稳定性和性能的优化,使其成为...
再者,Elasticsearch提供了强大的聚合分析功能,能对存储的大量数据进行近实时的统计分析。 要使用Elasticsearch,有几个最基本的概念是必须了解的,包括节点(Node)、索引(Index)、类型映射(Mapping)和文档...
1. **基础知识准备**:在学习之前,最好具备一定的Java基础,因为ElasticSearch是基于Java编写的。 2. **实践操作**:理论学习的同时,要动手实践,通过搭建自己的测试环境来加深理解。 3. **社区交流**:加入...
- **Elasticsearch vs Lucene**: ES在Java之上构建,简化了Lucene的使用,支持集群,解决了Lucene的一些复杂性和限制。 - **Elasticsearch vs Solr**: ES自带分布式协调,支持实时搜索,而Solr需借助Zookeeper进行...
**Elasticsearch技术解析与实战** Elasticsearch是一款开源、分布式、实时的全文搜索引擎,它以其强大的搜索功能和高可扩展性在IT行业中备受青睐。本书"elasticsearch技术解析与实战"深入浅出地介绍了Elasticsearch...
### Elasticsearch核心技术与实战笔记知识点概览 #### 一、ELK Stack概述 - **定义**:ELK Stack是由Elasticsearch、Logstash和Kibana组成的开源软件集合,旨在提供全面的数据抽取、搜索分析和数据可视化解决方案。...
【qiao-es-api】这部分可能是Elasticsearch客户端API的实现,用于和Elasticsearch服务器交互。常见的客户端API包括Java REST Client、Transport Client(已被弃用)和Jest等。此部分会涵盖以下知识点: 1. **连接...
Elasticsearch提供了Java API,使得开发者可以方便地在Java应用程序中集成Elasticsearch功能。主要包括以下操作: - **创建索引**:使用`client.admin().indices().prepareCreate(indexName)`来创建一个新的索引。 ...