- 浏览: 2184728 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (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开发之第八步之渡劫初期(八)
散仙在上篇文章中,介绍了关于ElasticSearch基本的增删改查的基本粒子,本篇呢,我们来学下稍微高级一点的知识:
(1)如何在ElasticSearch中批量提交索引 ?
(2)如何使用高级查询(包括,检索,排序,过滤,分页) ?
(3)如何组合多个查询 ?
(4)如何使用翻页深度查询 ?
(5)如何使用基本的聚合查询 ?
(一)首先,我们思考下,为什么要使用批量添加,这个毫无疑问,因为效率问题,举个在生活中的例子,假如我们有50个人,要去美国旅游,不使用批处理的方式是,给每一个人派一架飞机送到美国,那么这就需要50次飞机的来回往来,假如使用了批处理,现在的情况就是一个飞机坐50个人,只需一次即可把所有人都送到美国,效率可想而知,生活也有很多实际的例子,大家可以自己想想。
在原生的lucene中,以及solr中,这个批处理方式,实质是控制commit的时机,比如多少个提交一次,或者超过ranbuffersize的大小后自动提交,es封装了lucene的api提供bulk的方式来批量添加,原理也是,聚集一定的数量doc,然后发送一次添加请求。
(二)只要我们使用了全文检索,我们的业务就会有各种各样的api操作,包括,任意维度的字段查询,过滤掉某些无效的信息,然后根据某个字段排序,再取topN的结果集返回,使用数据库的小伙伴们,相信大家都不陌生,在es中,这些操作都是支持的,而且还非常高效,它能满足我们大部分的需求
(三)在es中,我们可以查询多个index,以及多个type,这一点是非常灵活地,我们,我们可以一次组装两个毫无关系的查询,发送到es服务端进行检索,然后获取结果。
(四)es中,通过了scorll的方式,支持深度分页查询,在数据库里,我们使用的是一个cursor游标来记录读取的偏移量,同样的在es中也支持,这样的查询方式,它通过一个scrollid记录了上一次查询的状态,能轻而易举的实现深度翻页,本质上是对了Lucene的SearchAfter的封装。
(五)es中,也提供了对聚合函数的支持,比如一些max,min,avg,count,sum等支持,除此之外还支持group,facet等操作,这些功能,在电商中应用非常广泛,基于lucene的solr和es都有很好的支持。
下面截图看下散仙的测试数据值:
源码demo如下:
package com.dongliang.es; import java.util.Date; import java.util.Map; import java.util.Map.Entry; import org.apache.lucene.index.Terms; import org.elasticsearch.action.bulk.BulkRequestBuilder; import org.elasticsearch.action.bulk.BulkResponse; import org.elasticsearch.action.search.MultiSearchResponse; import org.elasticsearch.action.search.SearchRequestBuilder; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.action.search.SearchType; import org.elasticsearch.client.Client; import org.elasticsearch.client.transport.TransportClient; import org.elasticsearch.common.transport.InetSocketTransportAddress; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentFactory; import org.elasticsearch.index.query.FilterBuilders; import org.elasticsearch.index.query.QueryBuilders; import org.elasticsearch.index.query.QueryStringQueryBuilder; import org.elasticsearch.search.SearchHit; import org.elasticsearch.search.aggregations.AggregationBuilders; import org.elasticsearch.search.aggregations.bucket.filters.InternalFilters.Bucket; import org.elasticsearch.search.sort.SortOrder; /** * @author 三劫散仙 * 搜索技术交流群:324714439 * 一个关于elasticsearch批量提交 * 和search query的的例子 * **/ public class ElasticSearchDao { //es的客户端实例 Client client=null; { //连接单台机器,注意ip和端口号,不能写错 client=new TransportClient(). addTransportAddress(new InetSocketTransportAddress("192.168.46.16", 9300)); } public static void main(String[] args)throws Exception { ElasticSearchDao es=new ElasticSearchDao(); //es.indexdata();//索引数据 //es.queryComplex(); es.querySimple(); //es.scorllQuery(); //es.mutilCombineQuery(); //es.aggregationQuery(); } /**组合分组查询*/ public void aggregationQuery()throws Exception{ SearchResponse sr = client.prepareSearch() .setQuery(QueryBuilders.matchAllQuery()) .addAggregation( AggregationBuilders.terms("1").field("type") ) // .addAggregation( // AggregationBuilders.dateHistogram("agg2") // .field("birth") // .interval(DateHistogram.Interval.YEAR) // ) .execute().actionGet(); // Get your facet results org.elasticsearch.search.aggregations.bucket.terms.Terms a = sr.getAggregations().get("1"); for(org.elasticsearch.search.aggregations.bucket.terms.Terms.Bucket bk:a.getBuckets()){ System.out.println("类型: "+bk.getKey()+" 分组统计数量 "+bk.getDocCount()+" "); } System.out.println("聚合数量:"+a.getBuckets().size()); //DateHistogram agg2 = sr.getAggregations().get("agg2"); //结果: // 类型: 1 分组数量 2 // 类型: 2 分组数量 1 // 类型: 3 分组数量 1 // 聚合数量:3 } /**多个不一样的请求组装*/ public void mutilCombineQuery(){ //查询请求1 SearchRequestBuilder srb1 =client.prepareSearch().setQuery(QueryBuilders.queryString("eng").field("address")).setSize(1); //查询请求2//matchQuery SearchRequestBuilder srb2 = client.prepareSearch().setQuery(QueryBuilders.matchQuery("title", "标题")).setSize(1); //组装查询 MultiSearchResponse sr = client.prepareMultiSearch().add(srb1).add(srb2).execute().actionGet(); // You will get all individual responses from MultiSearchResponse#getResponses() long nbHits = 0; for (MultiSearchResponse.Item item : sr.getResponses()) { SearchResponse response = item.getResponse(); for(SearchHit hits:response.getHits().getHits()){ String sourceAsString = hits.sourceAsString();//以字符串方式打印 System.out.println(sourceAsString); } nbHits += response.getHits().getTotalHits(); } System.out.println("命中数据量:"+nbHits); //输出: // {"title":"我是标题","price":25.65,"type":1,"status":true,"address":"血落星域风阳星","createDate":"2015-03-16T09:56:20.440Z"} // 命中数据量:2 client.close(); } /** * 翻页查询 * */ public void scorllQuery()throws Exception{ QueryStringQueryBuilder queryString = QueryBuilders.queryString("标题").field("title"); //TermQueryBuilder qb=QueryBuilders.termQuery("title", "我是标题"); SearchResponse scrollResp = client.prepareSearch("collection1") .setSearchType(SearchType.SCAN) .setScroll(new TimeValue(60000)) .setQuery(queryString) .setSize(100).execute().actionGet(); //100 hits per shard will be returned for each scroll while (true) { for (SearchHit hit : scrollResp.getHits().getHits()) { //Handle the hit... String sourceAsString = hit.sourceAsString();//以字符串方式打印 System.out.println(sourceAsString); } //通过scrollid来实现深度翻页 scrollResp = client.prepareSearchScroll(scrollResp.getScrollId()).setScroll(new TimeValue(600000)).execute().actionGet(); //Break condition: No hits are returned if (scrollResp.getHits().getHits().length == 0) { break; } } //输出 // {"title":"我是标题","price":25.65,"type":1,"status":true,"address":"血落星域风阳星","createDate":"2015-03-16T09:56:20.440Z"} // {"title":"标题","price":251.65,"type":1,"status":true,"address":"美国东部","createDate":"2015-03-16T10:33:58.743Z"} client.close(); } /**简单查询*/ public void querySimple()throws Exception{ SearchResponse sp = client.prepareSearch("collection1").execute().actionGet(); for(SearchHit hits:sp.getHits().getHits()){ String sourceAsString = hits.sourceAsString();//以字符串方式打印 System.out.println(sourceAsString); } //结果 // {"title":"我是标题","price":25.65,"type":1,"status":true,"address":"血落星域风阳星","createDate":"2015-03-16T09:56:20.440Z"} // {"title":"中国","price":205.65,"type":2,"status":true,"address":"河南洛阳","createDate":"2015-03-16T10:33:58.740Z"} // {"title":"标题","price":251.65,"type":1,"status":true,"address":"美国东部","createDate":"2015-03-16T10:33:58.743Z"} // {"title":"elasticsearch是一个搜索引擎","price":25.65,"type":3,"status":true,"address":"china","createDate":"2015-03-16T10:33:58.743Z"} } /**组合查询**/ public void queryComplex()throws Exception{ SearchResponse sp=client.prepareSearch("collection1")//检索的目录 .setTypes("core1")//检索的索引 .setSearchType(SearchType.DFS_QUERY_THEN_FETCH)//Query type .setQuery(QueryBuilders.termQuery("type", "1"))//查询--Query .setPostFilter(FilterBuilders.rangeFilter("price").from(10).to(550.23))//过滤 --Filter .addSort("price",SortOrder.DESC) //排序 -- sort .setFrom(0).setSize(20).setExplain(true)//topN方式 .execute().actionGet();//执行 System.out.println("本次查询命中条数: "+sp.getHits().getTotalHits()); for(SearchHit hits:sp.getHits().getHits()){ //String sourceAsString = hits.sourceAsString();//以字符串方式打印 //System.out.println(sourceAsString); Map<String, Object> sourceAsMap = hits.sourceAsMap(); for(Entry<String, Object> k:sourceAsMap.entrySet()){ System.out.println("name: "+k.getKey()+" value: "+k.getValue()); } System.out.println("============================================="); } //结果 // 本次查询命中条数: 2 // name: title value: 标题 // name: price value: 251.65 // name: address value: 美国东部 // name: status value: true // name: createDate value: 2015-03-16T10:33:58.743Z // name: type value: 1 // ============================================= // name: title value: 我是标题 // name: price value: 25.65 // name: address value: 血落星域风阳星 // name: status value: true // name: createDate value: 2015-03-16T09:56:20.440Z // name: type value: 1 // ============================================= client.close(); } /**索引数据*/ public void indexdata()throws Exception{ BulkRequestBuilder bulk=client.prepareBulk(); XContentBuilder doc=XContentFactory.jsonBuilder() .startObject() .field("title","中国") .field("price",205.65) .field("type",2) .field("status",true) .field("address", "河南洛阳") .field("createDate", new Date()).endObject(); //collection为索引库名,类似一个数据库,索引名为core,类似一个表 // client.prepareIndex("collection1", "core1").setSource(doc).execute().actionGet(); //批处理添加 bulk.add(client.prepareIndex("collection1", "core1").setSource(doc)); doc=XContentFactory.jsonBuilder() .startObject() .field("title","标题") .field("price",251.65) .field("type",1) .field("status",true) .field("address", "美国东部") .field("createDate", new Date()).endObject(); //collection为索引库名,类似一个数据库,索引名为core,类似一个表 // client.prepareIndex("collection1", "core1").setSource(doc).execute().actionGet(); //批处理添加 bulk.add(client.prepareIndex("collection1", "core1").setSource(doc)); doc=XContentFactory.jsonBuilder() .startObject() .field("title","elasticsearch是一个搜索引擎") .field("price",25.65) .field("type",3) .field("status",true) .field("address", "china") .field("createDate", new Date()).endObject(); //collection为索引库名,类似一个数据库,索引名为core,类似一个表 //client.prepareIndex("collection1", "core1").setSource(doc).execute().actionGet(); //批处理添加 bulk.add(client.prepareIndex("collection1", "core1").setSource(doc)); //发一次请求,提交所有数据 BulkResponse bulkResponse = bulk.execute().actionGet(); if (!bulkResponse.hasFailures()) { System.out.println("创建索引success!"); } else { System.out.println("创建索引异常:"+bulkResponse.buildFailureMessage()); } client.close();//释放资源 // System.out.println("索引成功!"); } }
想了解更多有关电商互联网公司的搜索技术和大数据技术的使用,请欢迎扫码关注微信公众号:我是攻城师(woshigcs)
本公众号的内容是有关搜索和大数据技术和互联网等方面内容的分享,也是一个温馨的技术互动交流的小家园,有什么问题随时都可以留言,欢迎大家来访!
发表评论
-
复盘一个Elasticsearch排序问题的剖析
2019-07-15 21:12 1173最近线上的es查询的 ... -
elasticsearch里面bulk的用法
2018-04-09 20:23 1424上篇文章介绍了在es里 ... -
elasticsearch里面的关于批量读取mget的用法
2018-04-04 16:01 1834es的api除了提供了基本 ... -
elasticsearch的查询流程分析
2018-04-02 20:29 1331我们都知道es是一个分 ... -
如何在elasticsearch里面使用深度分页功能
2018-03-28 18:13 2023前面的文章提到过es默认的from+size的分页方式返回的结 ... -
如何在Elasticsearch里面使用索引别名
2018-03-27 20:37 1681在elasticsearch里面给index起一个alias ... -
如何优雅的全量读取Elasticsearch索引里面的数据
2018-03-26 20:27 7656### (一)scroll的介绍 有时候我们可能想要读取整个 ... -
关于elaticsearch中更新数据的几种方式
2018-03-21 19:00 969作为一个成熟的框架, ... -
Elasticsearch里面的segment合并
2018-03-20 17:50 2095通过前面的文章,我 ... -
Elasticsearch如何保证数据不丢失?
2018-03-19 20:52 2144上篇文章提到过,在elasticsearch和磁盘之间还有一层 ... -
为什么说Elasticsearch搜索是近实时的?
2018-03-16 19:41 9460通过前面两篇文章的介绍,我们大概已经知道了 Elasticse ... -
Elasticsearch如何动态维护一个不可变的倒排索引
2018-03-15 21:34 1140上一篇文章中介绍了Elasticsearch中是如何搜索文本 ... -
Elasticsearch如何检索数据
2018-03-14 20:11 1074我们都知道Elasticsearch是一个全文检索引擎,那么它 ... -
如何备份ElasticSearch索引数据到HDFS上
2018-02-09 18:19 2424在ElasticSearch里面备份策略已经比较成熟了 ... -
Elasticsearch5.6.4集群搭建
2018-02-07 20:13 1341本次搭建的是一个三节点的集群 (一)es的安装 (1)下 ... -
如何使log4j生成json格式的log
2017-09-15 17:44 3831使用java开发项目时,log日志一般都是应用程序必不可少的一 ... -
理解elasticsearch的parent-child关系
2017-09-04 18:43 2843前面文章介绍了,在es里面的几种数据组织关系,包括array ... -
简述ElasticSearch里面复杂关系数据的存储方式
2017-08-18 20:10 2414在传统的数据库里面,对数据关系描述无外乎三种,一对一,一对多和 ... -
使用Java Rest Client操作Elasticsearch
2017-08-09 19:42 2272Elasticsearch作为一个成熟的开源框架,对主流的多种 ... -
ElasticSearch里面的偏好查询
2017-06-22 17:17 1306在es查询的时候我们可 ...
相关推荐
**Elasticsearch 入门到精通** Elasticsearch 是一个高度可扩展的开源全文搜索引擎,设计用于处理大量数据,提供实时分析和搜索功能。它基于 Lucene 库,但提供了更高级别的分布式、RESTful 风格的搜索和数据分析...
**Elasticsearch 入门与实战** Elasticsearch 是一个基于 Lucene 的开源全文搜索引擎,以其分布式、可扩展性、实时搜索以及强大的数据分析能力而受到广泛欢迎。它不仅支持文本搜索,还可以处理结构化和非结构化数据...
Elaticsearch,简称为es, es是一个开源的高扩展的分布式全文检索引擎,它可以近乎实时的存储、检索数据;本身扩展性很好,可以扩展到上百台服务器,处理PB级别的数据。es也使用Java开发并使用Lucene作为其核心来...
"Elasticsearch 入门操作" Elasticsearch 是一个基于 Lucene 库的搜索引擎,提供了一个分布式、支持多用户的全文搜索引擎,具有 HTTP Web 接口和无模式 JSON 文档。所有其他语言可以使用 RESTful API 通过端口 9200...
(狂神)ElasticSearch快速入门笔记,ElasticSearch基本操作以及爬虫(Java-ES仿京东实战),包含了小狂神讲的东西,特别适合新手学习,笔记保存下来可以多看看。好记性不如烂笔头哦~,ElasticSearch,简称es,es是一个...
### Elasticsearch入门教程知识点详解 #### 一、Elasticsearch安装与基本操作 1. **解压目录结构**: - 在解压后的Elasticsearch目录中,通常包含多个子目录和文件,例如`bin`目录包含了启动脚本,`config`目录...
全套 elasticsearch从入门到精通到运维 基于ES5.6版本 有视频 文档 快速上手
这篇入门学习笔记将引导初学者了解如何安装、配置以及使用Elasticsearch。 首先,让我们从安装开始。要安装Elasticsearch,你可以访问官方网站(https://www.elastic.co/cn/downloads/elasticsearch)下载最新版本...
**Elasticsearch 6.1 入门教程详解** Elasticsearch是一款强大的开源搜索引擎,以其分布式、实时、可扩展和高容错性而备受青睐。在6.1版本中,它进一步提升了性能和稳定性,提供了更丰富的功能。本文将基于"Elastic...
Elasticsearch是一款强大的开源搜索引擎,尤其在大数据领域中被广泛应用。它基于Lucene库构建,提供了分布式、...这个“大数据elasticsearch开源搜索引擎安装包”将带你踏入Elasticsearch的世界,开启数据探索之旅。
"ElasticSearch实战教程" ElasticSearch是一款分布式、RESTful 风格的搜索和数据分析引擎,能够达到近实时搜索,稳定,可靠,快速...本教程旨在帮助您快速入门ElasticSearch,掌握ElasticSearch的基本概念和实战应用。
"ElasticSearch 入门篇" ElasticSearch 是一个基于 Lucene 的搜索服务器,提供了一个分布式多用户能力的全文搜索引擎,基于 RESTful web 接口。ElasticSearch 是用 Java 开发的,并作为 Apache 许可条款下的开放...
Elasticsearch是一款基于Lucene的开源搜索引擎,它使用RESTful接口进行数据操作,数据以JSON格式存储。Elasticsearch以其高效的全文搜索功能,实时数据处理能力,以及易于使用的特性,在众多企业中得到了广泛应用,...
Elasticsearch 入门
Elasticsearch 是一款高度可扩展的全文搜索引擎,广泛应用于大数据分析、日志分析、实时搜索等领域。本教程将深入浅出地介绍Elasticsearch的基础知识,帮助初学者快速上手。 1. **Elasticsearch 概述** - Elastic...
**Elasticsearch 开发环境搭建与 BBoss 入门教程** Elasticsearch 是一个高度可扩展的开源全文搜索引擎,设计用于快速提供近实时的搜索和分析能力。BBoss(Business Boss)是基于Elasticsearch的一个强大且灵活的...
Elasticsearch 入门讲解 1. ELASTICSEARCH 初识 Elasticsearch(简称ES)是一款基于Lucene的开源分布式搜索引擎,以其强大的全文检索、实时分析和高可扩展性而闻名。它不仅用于传统的搜索功能,还广泛应用于日志...
Search入门详解:开启你的搜索之旅 ElasticSearch(ES)是一个强大的、基于Lucene的开源搜索服务器,专门设计用于云计算环境。它提供了实时、稳定、可靠且可扩展的搜索和分析功能,支持RESTful接口,使得操作简单...
Elasticsearch(简称ES)是一种基于Lucene的开源搜索引擎,主要设计用于分布式、实时的文档存储和搜索。它不仅能够高效地处理结构化和非结构化的数据,还提供了数据分析的功能,使得用户可以在海量数据中快速获取...
在本项目"springboot+elasticsearch"中,开发者提供了一个全面的入门教程,涵盖了Elasticsearch的基本操作,包括增、删、改、查等基本功能,这对于初学者理解这两者如何协同工作非常有帮助。 首先,让我们深入了解...