ElasticSearch的使用

什么是ElasticSearch?

什么是全文检索?
计算机索引程序通过扫描文章中的每一个词,对每一个词建立一个索引,指明该词在文章中出现的次数和位置,当用户查询时,检索程序就根据事先建立的索引进行查找,并将查找的结果反馈给用户的检索方式
全文检索? ==> 全部都搜索 ==> 如何实现全部都搜索? ==> 分词 单词永不重复 单词就是索引 单词是最小的搜索单位

要了解ElasticSearch,首先要了解以下几个概念

  1. 索引:存储数据的表结构 ,任何搜索数据,存放在索引对象上,用关系型数据库来表示就可以表示成数据库的一个表。
  2. 映射:即数据(文档)如何存储在索引对象上,存储的数据类型、是否存储、是否分词 …
  3. 文档:一条数据记录, 存在索引对象上,用关系型数据库来表示则可以表示为表中的一条记录。
  4. 文档类型:一个索引对象 存放多种类型数据, 数据用文档类型进行标识。
    总结:在编程时,建立索引对象 — 建立映射 — 存储数据【文档】 — 指定文档类型进行搜索数据【文档】

为什么要使用ElasticSearch?

字段模糊查询,涉及大数据属性问题 like模糊查询无法对数据列应用索引 只能一条条字符串比对查询,效率非常低下,因此产生一种解决方案:建立数据索引库,采用全文检索的方式进行 全文索引可以将文本进行切分,建立成一个个词条的索引,最后进行检索的优化(检索文本中的每个词与搜索项进行比对)

ElasticSearch的下载与插件的安装

下载链接官网
下载完成后的目录结构:
下载完成后的目录结构:
bin 存放 elasticSearch 运行命令
config 存放配置文件
lib 存放 elasticSearch 运行依赖 jar 包
modules 存放 elasticSearch 模块
plugins 存放插件

运行 elasticSearch/bin/elasticsearch.bat 文件
注意运行处理文件之前需要有Java_Home的环境

安装插件:需要安装两个插件: head与ik分词器
运行%elasticsearch%/bin/plugin.bat install mobz/elasticsearch-head命令
访问 http://localhost:9200/_plugin/head/
在这里插入图片描述
Ik分词器与ElasticSearch的集成
为什么要使用IK分词器
因为IK分词器使用最细粒度切分算法,采用智能分词,ElasticSearch默认的分词器会将字符切分成单个词条,不利于检索。
1、 下载开源项目
下载链接官网
2、 打包 ik 分词器
mvn clean 清空
mvn package 打包
3、 进入 target/release 目录
将下列文件 ,拷贝到 %es%/plugins/analysis-ik
在这里插入图片描述
4、 进入 target/release/config 目录
将所有配置文件,复制 %es%/config 下

5、 配置 elasticsearch.yml
在这里插入图片描述
6、 重启 es
发现 ik 分词器被加载
在这里插入图片描述
7、访问
http://localhost:9200/_analyze?analyzer=ik&pretty=true&text=我爱你中国

ElasticSearch的使用

  1. 首先导入ElasticSeach的Maven依赖包
		<!-- elasricSearch的依赖包 -->
		<dependency>
			<groupId>org.elasticsearch</groupId>
			<artifactId>elasticsearch</artifactId>
			<version>2.4.0</version>
		</dependency>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.12</version>
		</dependency>
		<!-- jackson的核心包 elasticSearch本身集成了jackson -->
		<dependency>
			<groupId>com.fasterxml.jackson.core</groupId>
			<artifactId>jackson-core</artifactId>
			<version>2.8.1</version>
		</dependency>
		<dependency>
			<groupId>com.fasterxml.jackson.core</groupId>
			<artifactId>jackson-databind</artifactId>
			<version>2.8.1</version>
		</dependency>
		<dependency>
			<groupId>com.fasterxml.jackson.core</groupId>
			<artifactId>jackson-annotations</artifactId>
			<version>2.8.1</version>
		</dependency>
  1. 建立文档,自动创建索引
	@Test
	//直接在ElasticSearch中建立文档,自动创建索引
	public  void demo1() throws Exception{
		//创建连接搜索服务器对象
		Client client = TransportClient.builder().build().addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"),9300));
		//描述json数据
		/**
		 * {id:xxx,title:xxx,content:xxxx}
		 */
		XContentBuilder builder = XContentFactory.jsonBuilder().startObject()
				.field("id",1)
				.field("title","ElasticSearch是一个基于Lucene的搜索服务器")
				.field("contend","它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java开发的,并作为Apache许可条款下的开放源码发布,是当前流行的企业级搜索引擎。设计用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便。")
				.endObject();
		//建立文档对象
		client.prepareIndex("blog1", "article", "1").setSource(builder).get();
		//关闭搜索服务器操作
		client.close();
	}
  1. 搜索创建的文档对象
//搜索在ElasticSerach中创建的文档对象
	@Test
	public void demo2()throws Exception{
		//简历client对象
		Client client = TransportClient.builder().build().addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"),9300));

		//搜索数据
		//boolQuery 布尔查询。可以用来组合多个查询条件
		//fuzzyQuery相似度查询
		//matchQuery查询所有数据
		//regexQuery正则表达式查询
		//termquery 词条查询
		//这里的get相当于exectue.actionGet();
		//得到查询响应对象
		SearchResponse searchResponse = client.prepareSearch("blog1").setTypes("article").setQuery(QueryBuilders.matchAllQuery()).get();
		//获取命中次数,查询结果有多少对象
		printResult(searchResponse);
		
		//关闭连接
		client.close();
	}
  1. 查询的各种使用
@Test
	//各种查询的使用
	public void demo3()throws Exception{
		//简历client对象
		
		Client client = TransportClient.builder().build().addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"),9300));
		//进行分词查询
		//SearchResponse searchResponse = client.prepareSearch("blog1").setTypes("article").setQuery(QueryBuilders.queryStringQuery("全面")).get();
		//默认的分词器是将内容一个词一个词的划分,因此模糊查询不到
		//进行词条查询
		//SearchResponse searchResponse = client.prepareSearch("blog1").setTypes("article").setQuery(QueryBuilders.wildcardQuery("contend", "*全文*")).get();
		//进行词条查询
		SearchResponse searchResponse = client.prepareSearch("blog2").setTypes("article").setQuery(QueryBuilders.termQuery("content", "搜索")).get();

		//获取命中次数,查询结果有多少对象
		printResult(searchResponse);
		
		//关闭连接
		client.close();
	}
  1. 创建索引
@Test
	//索引操作
	public void demo4()throws Exception{
		//简历client对象
		
		Client client = TransportClient.builder().build().addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"),9300));
		
		//创建索引
		client.admin().indices().prepareCreate("blog2").get();
		
		//删除索引
		//client.admin().indices().prepareDelete("blog2").get();
		client.close();
	}
  1. 创建映射,根据IK分词器进行分词
	@Test
	//映射操作 创建映射
	public void demo5()throws Exception{
		//简历client对象
		
		Client client = TransportClient.builder().build().addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"),9300));
		
		//添加映射
		XContentBuilder builder = XContentFactory.jsonBuilder().startObject().startObject("article").startObject("properties")
				.startObject("id").field("type","integer").field("store","yes").endObject()
				.startObject("title").field("type","string").field("store","yes").field("analyzer","ik").endObject()
				.startObject("content").field("type","string").field("store","yes").field("analyzer","ik").endObject()
				.endObject().endObject().endObject();
		
		PutMappingRequest mapping = Requests.putMappingRequest("blog2").type("article").source(builder);
		
		client.admin().indices().putMapping(mapping).get();
		client.close();
	}
  1. 对已经存在的数据转换成json进行文档的添加
	@Test
	//对已经存在的数据转化成json数据进行增加文档
	public  void demo6() throws Exception{
		//创建连接搜索服务器对象
		Client client = TransportClient.builder().build().addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"),9300));
		
		//描述json数据
		/**
		 * {id:xxx,title:xxx,content:xxxx}
		 */
		Atricle article = new Atricle();
		article.setId(2);
		article.setTitle("搜索工作的创建其实很快乐");
		article.setContent("我们希望搜索解决方案要运行速度快,我们希望能有一个零配置和一个完全免费的搜索模式,我们希望能够简单地使用JSON通过HTTP来索引数据,我们希望我们的搜索服务器始终可用,我们希望能够从一台开始并扩展到数百台,我们要实时搜索,我们要简单的多租户,我们希望建立一个云的解决方案。因此我们利用Elasticsearch来解决所有这些问题及可能出现的更多其它问题。");
		
		ObjectMapper objectMapper = new ObjectMapper();
		
		
		//基于jackson将数据传入到es 建立文档
		//client.prepareIndex("blog2","article",article.getId().toString()).setSource(objectMapper.writeValueAsString(article)).get();
		
		//修改文档 修改一
		//client.prepareUpdate("blog2", "article", article.getId().toString()).setDoc(objectMapper.writeValueAsString(article)).get();
		
		//修改文档 修改二
		//client.update(new UpdateRequest("blog2","article",article.getId().toString()).doc(objectMapper.writeValueAsString(article))).get();
		
		//删除文档 方法一
		//client.prepareDelete("blog2", "article", article.getId().toString()).get();
		
		//删除文档 方法二
		client.delete(new DeleteRequest("blog2", "article", article.getId().toString())).get();
		
		//关闭搜索服务器操作
		client.close();
	}
  1. ElasticSearch的分页查询
	//搜索在ElasticSerach中创建的文档对象 分页查询
	@Test
	public void demo8()throws Exception{
		//简历client对象
		Client client = TransportClient.builder().build().addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"),9300));

		SearchRequestBuilder searchRequestBuilder = client.prepareSearch("blog2").setTypes("article").setQuery(QueryBuilders.matchAllQuery());
		//在get之前设置哪里开始查询,设置查询多少条数据
		SearchResponse searchResponse = searchRequestBuilder.setFrom(5).setSize(5).get();
		//获取命中次数,查询结果有多少对象
		printResult(searchResponse);
		
		//关闭连接
		client.close();
	}
  1. 高亮查询结果处理
@Test
	public void demo9()throws Exception{
		//简历client对象
		Client client = TransportClient.builder().build().addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"),9300));

		ObjectMapper objectMapper = new ObjectMapper();
		
		SearchRequestBuilder searchRequestBuilder = client.prepareSearch("blog2").setTypes("article").setQuery(QueryBuilders.termQuery("content", "搜索"));
	
		//高亮定义
		//需要对哪个字段进行高亮
		searchRequestBuilder.addHighlightedField("content");
		//前置元素
		searchRequestBuilder.setHighlighterPreTags("<em>");
		//后置元素
		searchRequestBuilder.setHighlighterPostTags("</em>");
		
		//在get之前设置哪里开始查询,设置查询多少条数据
		SearchResponse searchResponse = searchRequestBuilder.get();
		//获取命中次数,查询结果有多少对象
		SearchHits hits = searchResponse.getHits();
		//获得查询结果
		System.out.println("查询结果有:" +hits.getTotalHits()+"条");
		Iterator<SearchHit> iterator = hits.iterator();
		while (iterator.hasNext()) {
			//每个查询对象
			SearchHit searchHit = iterator.next();
			//将高亮处理后内容,替换原有内容(原有内容,可能会出现显示不全)
			//获取高亮显示域
			Map<String, HighlightField> fields = searchHit.getHighlightFields();
			//获取title的高亮显示
			HighlightField titleField = fields.get("content");
			//获取到原有内容中 每个高亮显示集中位置,高亮片段
			Text[] fragments = titleField.fragments();
			
			String title = "";
			for (Text text : fragments) {
				title +=text;
			}
			
			//将json数据转成Articlt对象
		   Atricle atricle =	objectMapper.readValue(searchHit.getSourceAsString(),Atricle.class);
			//用高亮后的内容,替换原有内容
		   atricle.setContent(title); 
			//获取字符串格式打印
			System.out.println(atricle);	
		}
		
		//关闭连接
		client.close();
	}
  1. 封装查询结果
//抽取查询结果封装
	private void printResult(SearchResponse searchResponse) {
		SearchHits hits = searchResponse.getHits();
		//获得查询结果
		System.out.println("查询结果有:" +hits.getTotalHits()+"条");
		Iterator<SearchHit> iterator = hits.iterator();
		while (iterator.hasNext()) {
			//每个查询对象
			SearchHit searchHit = iterator.next();
			//获取字符串格式打印
			System.out.println(searchHit.getSourceAsString());
			System.out.println("title"+searchHit.getSource().get("title"));
			
		}
	}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值