title: elasticsearch
date: 2019-08-03 12:37:18
categories:
- 后端
- 搜索引擎
tags: - 后端
- 搜索引擎
ElasticSearch特点
-
百度百科简介:ElasticSearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java语言开发的,并作为Apache许可条款下的开放源码发布,是一种流行的企业级搜索引擎。ElasticSearch用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便。官方客户端在Java、.NET(C#)、PHP、Python、Apache Groovy、Ruby和许多其他语言中都是可用的。根据DB-Engines的排名显示,Elasticsearch是最受欢迎的企业搜索引擎,其次是Apache Solr,也是基于Lucene
-
Elasticsearch使用Lucene,并试图通过JSON和Java API提供其所有特性。它支持facetting和percolating,如果新文档与注册查询匹配,这对于通知非常有用。另一个特性称为“网关”,处理索引的长期持久性;例如,在服务器崩溃的情况下,可以从网关恢复索引。Elasticsearch支持实时GET请求,适合作为NoSQL数据存储,但缺少分布式事务。
-
cluster:代表一个集群,集群中有多个节点,其中有一个为主节点,这个主节点是可以通过选举产生的,主从节点是对于集群内部来说的。es的一个概念就是去中心化,字面上理解就是无中心节点,这是对于集群外部来说的,因为从外部来看es集群,在逻辑上是个整体,你与任何一个节点的通信和与整个es集群通信是等价的
-
shards:代表索引分片,es可以把一个完整的索引分成多个分片,这样的好处是可以把一个大的索引拆分成多个,分布到不同的节点上。构成分布式搜索。分片的数量只能在索引创建前指定,并且索引创建后不能更改。
-
replicas:代表索引副本,es可以设置多个索引的副本,副本的作用一是提高系统的容错性,当某个节点某个分片损坏或丢失时可以从副本中恢复。二是提高es的查询效率,es会自动对搜索请求进行负载均衡
-
recovery:代表数据恢复或叫数据重新分布,es在有节点加入或退出时会根据机器的负载对索引分片进行重新分配,挂掉的节点重新启动时也会进行数据恢复
-
river:代表es的一个数据源,也是其它存储方式(如:数据库)同步数据到es的一个方法。它是以插件方式存在的一个es服务,通过读取river中的数据并把它索引到es中,官方的river有couchDB的,RabbitMQ的,Twitter的,Wikipedia的
-
gateway:代表es索引快照的存储方式,es默认是先把索引存放到内存中,当内存满了时再持久化到本地硬盘。gateway对索引快照进行存储,当这个es集群关闭再重新启动时就会从gateway中读取索引备份数据。es支持多种类型的gateway,有本地文件系统(默认),分布式文件系统,Hadoop的HDFS和amazon的s3云存储服务
-
discovery.zen:代表es的自动发现节点机制,es是一个基于p2p的系统,它先通过广播寻找存在的节点,再通过多播协议来进行节点之间的通信,同时也支持点对点的交互
-
Transport:代表es内部节点或集群与客户端的交互方式,默认内部是使用tcp协议进行交互,同时它支持http协议(json格式)、thrift、servlet、memcached、zeroMQ等的传输协议(通过插件方式集成)
-
建立文本库–建立索引–执行搜索–过滤结果
使用
-
构建模板类 EsBlog
package com.test.demo3.domain.es; import org.springframework.data.elasticsearch.annotations.Document; import javax.persistence.Id; import java.io.Serializable;//java提供的常用的通用数据保存和读取接口 @Document(indexName = "blog",type = "blog" )//表示文档的注解,索引是blog public class EsBlog implements Serializable { private static final long serialVersionUID = 1l; @Id//表示主键 private String id; private String title; private String summary; private String content; protected EsBlog() { //jpa的要求哦 } public EsBlog(String title, String summary, String content) { this.title = title; this.summary = summary; this.content = content; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getSummary() { return summary; } public void setSummary(String summary) { this.summary = summary; } public String getContent() { return content; } public void setContent(String content) { this.content = content; } @Override public String toString() { return "EsBlog{" + "id='" + id + '\'' + ", title='" + title + '\'' + ", summary='" + summary + '\'' + ", content='" + content + '\'' + '}'; } }
-
测试类(包含接口)
package com.test.demo3.repository.es; import com.test.demo3.domain.es.EsBlog; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; /** * 分页查询博客(文章标题或文章摘要或文章内容) * 接口 */ public interface EsBlogRepository extends ElasticsearchRepository<EsBlog,String> { Page<EsBlog> findDistinctByTitleContainingOrSummaryContainingOrContentContaining(String title, String summary, String content, Pageable pageable); } package com.test.demo3; import com.test.demo3.domain.es.EsBlog; import com.test.demo3.repository.es.EsBlogRepository; import static org.assertj.core.api.Assertions.assertThat; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; import org.springframework.test.context.junit4.SpringRunner; /** * 测试用例 */ @RunWith(SpringRunner.class) @SpringBootTest public class EsBlogRepositorytest { @Autowired private EsBlogRepository esBlogRepository; @Before public void initRRepositoryData(){ //清楚所有数据 esBlogRepository.deleteAll(); esBlogRepository.save(new EsBlog("登鹳雀楼","王之涣","白日依山尽,黄河入海流,欲穷千里目,更上一层楼")); esBlogRepository.save(new EsBlog("相思","王维","红豆生南国,春来发几枝。愿君多采撷,此物最相思")); esBlogRepository.save(new EsBlog("静夜思","李白","床前明月光,疑是地上霜。举头望明月,低头思故乡")); } @Test public void testFindDistinctByTitleContainingOrSummaryContainingOrContentContaining(){ Pageable pageable = new PageRequest(0,20) ;//分页对象 String title = "思"; String summary = "相思"; String content = "相思"; Page<EsBlog> page = esBlogRepository.findDistinctByTitleContainingOrSummaryContainingOrContentContaining(title,summary,content,pageable); assertThat(page.getTotalElements()).isEqualTo(2); System.out.println("--------------start"); for (EsBlog blog:page.getContent()) System.out.println(blog.toString()); } }
-
在运行测试类之前需要打开elasticsearch:windows下打开次文件夹中的elasticsearch.bat(需要配置Java1.8的环境)
-
结果
-
该进,为了添加到8080端口中
package com.test.demo3; import com.test.demo3.domain.es.EsBlog; import com.test.demo3.repository.es.EsBlogRepository; import static org.assertj.core.api.Assertions.assertThat; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; import org.springframework.test.context.junit4.SpringRunner; /** * 测试用例 */ @RunWith(SpringRunner.class) @SpringBootTest public class EsBlogRepositorytest { @Autowired private EsBlogRepository esBlogRepository; @Before public void initRRepositoryData(){ //清楚所有数据 esBlogRepository.deleteAll(); esBlogRepository.save(new EsBlog("登鹳雀楼","王之涣","白日依山尽,黄河入海流,欲穷千里目,更上一层楼")); esBlogRepository.save(new EsBlog("相思","王维","红豆生南国,春来发几枝。愿君多采撷,此物最相思")); esBlogRepository.save(new EsBlog("静夜思","李白","床前明月光,疑是地上霜。举头望明月,低头思故乡")); } @Test public void testFindDistinctByTitleContainingOrSummaryContainingOrContentContaining(){ Pageable pageable = new PageRequest(0,20) ;//分页对象 String title = "思"; String summary = "相思"; String content = "相思"; Page<EsBlog> page = esBlogRepository.findDistinctByTitleContainingOrSummaryContainingOrContentContaining(title,summary,content,pageable); assertThat(page.getTotalElements()).isEqualTo(2); System.out.println("--------------start"); for (EsBlog blog:page.getContent()) System.out.println(blog.toString()); } }
-
运行示例