`
qindongliang1922
  • 浏览: 2189529 次
  • 性别: Icon_minigender_1
  • 来自: 北京
博客专栏
7265517b-f87e-3137-b62c-5c6e30e26109
证道Lucene4
浏览量:117687
097be4a0-491e-39c0-89ff-3456fadf8262
证道Hadoop
浏览量:126090
41c37529-f6d8-32e4-8563-3b42b2712a50
证道shell编程
浏览量:60046
43832365-bc15-3f5d-b3cd-c9161722a70c
ELK修真
浏览量:71420
社区版块
存档分类
最新评论

ElasticSearch入门之彼行我释(四)

    博客分类:
  • ELK
阅读更多




散仙在上篇文章中,介绍了关于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)
本公众号的内容是有关搜索和大数据技术和互联网等方面内容的分享,也是一个温馨的技术互动交流的小家园,有什么问题随时都可以留言,欢迎大家来访!






  • 大小: 353.1 KB
  • 大小: 247.3 KB
2
3
分享到:
评论

相关推荐

    《ElasticSearch入门到实战》电子书,从入门到进阶实战项目的教程文档,框架SpringBoot框架整合ES.zip

    **Elasticsearch 入门与实战** Elasticsearch 是一个基于 Lucene 的开源全文搜索引擎,以其分布式、可扩展性、实时搜索以及强大的数据分析能力而受到广泛欢迎。它不仅支持文本搜索,还可以处理结构化和非结构化数据...

    ElasticSearch入门到精通(基于ELK技术栈ElasticSearch7.8.版本).rar

    **Elasticsearch 入门到精通** Elasticsearch 是一个高度可扩展的开源全文搜索引擎,设计用于处理大量数据,提供实时分析和搜索功能。它基于 Lucene 库,但提供了更高级别的分布式、RESTful 风格的搜索和数据分析...

    ElasticSearch入门.pdf

    Elaticsearch,简称为es, es是一个开源的高扩展的分布式全文检索引擎,它可以近乎实时的存储、检索数据;本身扩展性很好,可以扩展到上百台服务器,处理PB级别的数据。es也使用Java开发并使用Lucene作为其核心来...

    es入门操作-elasticsearch入门操作

    "Elasticsearch 入门操作" Elasticsearch 是一个基于 Lucene 库的搜索引擎,提供了一个分布式、支持多用户的全文搜索引擎,具有 HTTP Web 接口和无模式 JSON 文档。所有其他语言可以使用 RESTful API 通过端口 9200...

    (狂神)ElasticSearch快速入门笔记,ElasticSearch基本操作以及爬虫(Java-ES仿京东实战)

    (狂神)ElasticSearch快速入门笔记,ElasticSearch基本操作以及爬虫(Java-ES仿京东实战),包含了小狂神讲的东西,特别适合新手学习,笔记保存下来可以多看看。好记性不如烂笔头哦~,ElasticSearch,简称es,es是一个...

    Elasticsearch入门教程

    ### Elasticsearch入门教程知识点详解 #### 一、Elasticsearch安装与基本操作 1. **解压目录结构**: - 在解压后的Elasticsearch目录中,通常包含多个子目录和文件,例如`bin`目录包含了启动脚本,`config`目录...

    ElasticSearch入门到精通到运维全套资料

    全套 elasticsearch从入门到精通到运维 基于ES5.6版本 有视频 文档 快速上手

    Elasticsearch入门学习笔记

    这篇入门学习笔记将引导初学者了解如何安装、配置以及使用Elasticsearch。 首先,让我们从安装开始。要安装Elasticsearch,你可以访问官方网站(https://www.elastic.co/cn/downloads/elasticsearch)下载最新版本...

    Elasticsearch 6.1官方入门教程.rar

    **Elasticsearch 6.1 入门教程详解** Elasticsearch是一款强大的开源搜索引擎,以其分布式、实时、可扩展和高容错性而备受青睐。在6.1版本中,它进一步提升了性能和稳定性,提供了更丰富的功能。本文将基于"Elastic...

    Elasticsearch入门.zip

    Elasticsearch是一款强大的开源搜索引擎,尤其在大数据领域中被广泛应用。它基于Lucene库构建,提供了分布式、...这个“大数据elasticsearch开源搜索引擎安装包”将带你踏入Elasticsearch的世界,开启数据探索之旅。

    ElasticSearch实战教程

    "ElasticSearch实战教程" ElasticSearch是一款分布式、RESTful 风格的搜索和数据分析引擎,能够达到近实时搜索,稳定,可靠,快速...本教程旨在帮助您快速入门ElasticSearch,掌握ElasticSearch的基本概念和实战应用。

    第一章 ElasticSearch入门篇.docx

    "ElasticSearch 入门篇" ElasticSearch 是一个基于 Lucene 的搜索服务器,提供了一个分布式多用户能力的全文搜索引擎,基于 RESTful web 接口。ElasticSearch 是用 Java 开发的,并作为 Apache 许可条款下的开放...

    Elastic Search搭建使用教程.pdf(内含ElasticSearch教程权威指南)

    Elasticsearch是一款基于Lucene的开源搜索引擎,它使用RESTful接口进行数据操作,数据以JSON格式存储。Elasticsearch以其高效的全文搜索功能,实时数据处理能力,以及易于使用的特性,在众多企业中得到了广泛应用,...

    Elasticsearch 入门.pdf

    Elasticsearch 入门

    最完整的Elasticsearch 基础教程

    Elasticsearch 是一款高度可扩展的全文搜索引擎,广泛应用于大数据分析、日志分析、实时搜索等领域。本教程将深入浅出地介绍Elasticsearch的基础知识,帮助初学者快速上手。 1. **Elasticsearch 概述** - Elastic...

    ES查询客户端,elasticsearch可视化工具 elasticsearch查询客户端

    Elasticsearch(简称ES)是一款强大的开源搜索引擎,广泛应用于数据检索、分析和管理。作为分布式、RESTful风格的搜索和数据分析引擎,Elasticsearch能够提供实时、高可用性以及可扩展的搜索功能。在进行日常的数据...

    bboss-elasticsearch开发环境搭建和开发入门视频教程.

    **Elasticsearch 开发环境搭建与 BBoss 入门教程** Elasticsearch 是一个高度可扩展的开源全文搜索引擎,设计用于快速提供近实时的搜索和分析能力。BBoss(Business Boss)是基于Elasticsearch的一个强大且灵活的...

    Elasticsearch入门讲解

    Elasticsearch 入门讲解 1. ELASTICSEARCH 初识 Elasticsearch(简称ES)是一款基于Lucene的开源分布式搜索引擎,以其强大的全文检索、实时分析和高可扩展性而闻名。它不仅用于传统的搜索功能,还广泛应用于日志...

    ES基础入门培训-零基础门槛

    Search入门详解:开启你的搜索之旅 ElasticSearch(ES)是一个强大的、基于Lucene的开源搜索服务器,专门设计用于云计算环境。它提供了实时、稳定、可靠且可扩展的搜索和分析功能,支持RESTful接口,使得操作简单...

    elasticsearch基础入门.pptx

    Elasticsearch(简称ES)是一种基于Lucene的开源搜索引擎,主要设计用于分布式、实时的文档存储和搜索。它不仅能够高效地处理结构化和非结构化的数据,还提供了数据分析的功能,使得用户可以在海量数据中快速获取...

Global site tag (gtag.js) - Google Analytics