Elasticsearch简介及SpringBoot整合ES实例

Elasticsearch简介****

1.1 Elasticsearch**(以下简称ES)**定义

Elasticsearch 是一个开源的搜索引擎。 建立在全文搜索引擎库 Apache Lucene 基础之上。它的内部使用 Lucene 做索引与搜索,但是它的目的是使全文检索变得简单,通过隐藏 Lucene 的复杂性,取而代之的提供一套简单一致的 RESTful API。

Elasticsearch 不仅仅只是一个全文搜索引擎。 它可以被下面这样准确的形容:、

一个分布式的实时文档存储,每个字段可以被索引与搜索——作数据库用

一个分布式实时分析搜索引擎,能胜任上百个服务节点的扩展,并支持PB 级别的结构化或者非结构化数据

1.2 ES发展历程

Elasticsearch 后来作为一家公司(Elastic公司)进行运作,定位为数据搜索和分析平台。ES现在可以与Java、Ruby、Python、PHP、Perl、.NET等多种客户端集成。也可与Hadoop、Spark等大数据分析平台进行集成,功能十分强大。

基于Elasticsearch衍生出了一系列开源软件,统称为 Elatic Stack。

说明:

因为logstash比较耗内存,所以用Beats来替代。

为避免版本混乱,从5.0开始,Elastic公司将各组件的版本号统一。使用时,各组件版本号应一致(版本号形式:x.y.z,z可以不同)。

1.3 ES特性

官网的介绍: https://www.elastic.co/cn/products/elasticsearch

速度快、易扩展、弹性、灵活、操作简单、多语言客户端、X-Pack、hadoop/spark强强联手、开箱即用。

分布式:横向扩展非常灵活
全文检索:基于lucene的强大的全文检索能力;
近实时搜索和分析:数据进入ES,可达到近实时搜索,还可进行聚合分析
高可用:容错机制,自动发现新的或失败的节点,重组和重新平衡数据
模式自由:ES的动态mapping机制可以自动检测数据的结构和类型,创建索引并使数据可搜索。
RESTful API:JSON + HTTP

1.4 ES应用场景案例

维基百科使用Elasticsearch来进行全文搜做并高亮显示关键词,以及提供search-as-you-type、did-you-mean等搜索建议功能。

GitHub使用Elasticsearch来检索超过1300亿行代码

英国卫报使用Elasticsearch来处理访客日志,以便能将公众对不同文章的反应实时地反馈给各位编辑

1.5 ES架构

说明:

Gateway是ES用来存储索引的文件系统,支持多种类型。
Gateway的上层是一个分布式的lucene框架。
Lucene之上是ES的模块,包括:索引模块、搜索模块、映射解析模块等
ES模块之上是 Discovery、Scripting和第三方插件。Discovery是ES的节点发现模块,不同机器上的ES节点要组成集群需要进行消息通信,集群内部需要选举master节点,这些工作都是由Discovery模块完成。支持多种发现机制,如 Zen 、EC2、gce、Azure。Scripting用来支持在查询语句中插入javascript、python等脚本语言,scripting模块负责解析这些脚本,使用脚本语句性能稍低。ES也支持多种第三方插件。
再上层是ES的传输模块和JMX.传输模块支持多种传输协议,如 Thrift、memecached、http,默认使用http。JMX是java的管理框架,用来管理ES应用。
最上层是ES提供给用户的接口,可以通过RESTful接口和ES集群进行交互。

1.6 ES核心概念

Near Realtime(NRT) 近实时****:****数据提交索引后,立马就可以搜索到。

Cluster 集群****:****一个集群由一个唯一的名字标识,默认为“elasticsearch”。集群名称非常重要,具有相同集群名的节点才会组成一个集群。集群名称可以在配置文件中指定。

Node 节点:存储集群的数据,参与集群的索引和搜索功能。像集群有名字,节点也有自己的名称,默认在启动时会以一个随机的UUID的前七个字符作为节点的名字,你可以为其指定任意的名字。通过集群名在网络中发现同伴组成集群。一个节点也可是集群。

Index 索引****:****一个索引是一个文档的集合(等同于solr中的集合)。每个索引有唯一的名字,通过这个名字来操作它。一个集群中可以有任意多个索引。
****Type 类型:****指在一个索引中,可以索引不同类型的文档,如用户数据、博客数据。从6.0.0 版本起已废弃,一个索引中只存放一类数据。
****Document 文档:****被索引的一条数据,索引的基本信息单元,以JSON格式来表示。
****Shard 分片:****在创建一个索引时可以指定分成多少个分片来存储。每个分片本身也是一个功能完善且独立的“索引”,可以被放置在集群的任意节点上。分片的好处:允许我们水平切分/扩展容量、可在多个分片上进行分布式的、并行的操作,提高系统的性能和吞吐量。

注意:分片数创建索引时指定,创建后不可改了。备份数可以随时改。
****Replication 备份:****一个分片可以有多个备份(副本)。备份的好处:
高可用。一个主分片挂了,副本分片就顶上去
扩展搜索的并发能力、吞吐量。搜索可以在所有的副本上并行运行。-高并发下副本也可搜索

为了方便理解,一个ES和数据库的对比****:****

RDBMS

Elasticsearch

数据库(database)

索引(index)

表(table)

类型(type)(6.0.0后废弃)

行(row)

文档(document)

列(column)

字段(field)

表结构(schema)

映射(mapping)

索引

反向索引

SQL

查询DSL

SELECT * FROM TABLE

GET http://…

INSERT INTO TABLE ,UPDATE TABLE

PUT http://…

DELETE

DELETE http://…

ES安装及使用****

2.1安装

官网下载地址: https://www.elastic.co/downloads/elasticsearch

JDK版本: 1.8

2.2启动

解压安装包到相应路径,进入bin目录中双击elasticsearch.bat等待启动完毕。

打开浏览器,输入http://localhost:9200,显式以下画面,说明ES安装成功。

2.3 ES配置说明

elasticsearch的config文件夹里面有两个配置件:elasticsearch.yml和logging.yml,第一个是es的基本配置文件,第二个是日志配置文件,es也是使用log4j来记录日 志的,所以logging.yml里的设置按普通log4j配置文件来设置就行了。下面主要说下elasticsearch.yml这个文件中的配置项:

cluster.name: elasticsearch

配置es的集群名称,默认是elasticsearch,es会自动发现在同一网段下的es,如果在同一网段下有多个集群,就可以用这个属性来区分不同的集群。

node.name: “Franz Kafka”

节点名,默认随机指定一个name列表中名字,该列表在es的jar包中config文件夹里name.txt文件中,其中有很多作者添加的有趣名字。

node.master: true

指定该节点是否有资格被选举成为node,默认是true,es是默认集群中的第一台机器为master,如果这台机挂了就会重新选举master。

node.data: true

指定该节点是否存储索引数据,默认为true。

index.number_of_shards: 5

设置默认索引分片个数,默认为5片。

index.number_of_replicas: 1

设置默认索引副本个数,默认为1个副本。

path.conf: /path/to/conf

设置配置文件的存储路径,默认是es根目录下的config文件夹。

path.data: /path/to/data

设置索引数据的存储路径,默认是es根目录下的data文件夹,可以设置多个存储路径,用逗号隔开,例:

path.data: /path/to/data1,/path/to/data2

path.work: /path/to/work

设置临时文件的存储路径,默认是es根目录下的work文件夹。

path.logs: /path/to/logs

设置日志文件的存储路径,默认是es根目录下的logs文件夹

path.plugins: /path/to/plugins

设置插件的存放路径,默认是es根目录下的plugins文件夹

下面是一些查询时的慢日志参数设置

index.search.slowlog.level: TRACE

index.search.slowlog.threshold.query.warn: 10s

index.search.slowlog.threshold.query.info: 5s

index.search.slowlog.threshold.query.debug: 2s

index.search.slowlog.threshold.query.trace: 500ms

index.search.slowlog.threshold.fetch.warn: 1s

index.search.slowlog.threshold.fetch.info: 800ms

index.search.slowlog.threshold.fetch.debug:500ms

index.search.slowlog.threshold.fetch.trace: 200ms

2.4 ES端口说明

9300端口: ES节点之间通讯使用,9300是tcp通讯端口,集群间和TCPClient 都走的它。
9200端口: ES节点和外部通讯使用,9200是http协议的RESTful接口。

2.5安装可视化工具Kibana

2.5.1 安装

下载安装包,需要和ES版本匹配:

https://www.elastic.co/downloads/kibana,解压到安装目录即可

2.5.2 配置

在目录config/kibana.yml中配置 elasticsearch.url的值为 ES的访问地址

2.5.3 启动

启动bin/kibana

访问地址:http://localhost:5601

2.6集成Ikanalyzer

2.6.1 安装

获取 ES-IKAnalyzer插件,需要和ES版本一致

地址: https://github.com/medcl/elasticsearch-analysis-ik/releases

将 ik的压缩包解压到 ES安装目录的plugins/目录下,重启ES,出现如下图说明安装成功

Springboot整合Elasticsearch案例

3.1 springboot配置

pom 文件配置:

s

<!--添加spring-data-elasticsearch的依赖-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>e

application.yaml配置:

data:
elasticsearch:
cluster-name: elasticsearch #默认为elasticsearch
cluster-nodes: 127.0.0.1:9300 #配置es节点信息,逗号分隔,如果没有指定,则启动ClientNode
properties:
path:
logs: ./elasticsearch/log #elasticsearch日志存储目录
data: ./elasticsearch/data #elasticsearch数据存储目录

3.2 数据存储

将D:\Lucene_Document 路径下的文件解析存储到es中

@Document(indexName = “test-file”,type = “file”)
@Mapping(mappingPath= “index_file.json”)
@Data
public class DocFile {

@Id
private String id;

//@Field(analyzer = “ik_max_word”,searchAnalyzer = “ik_max_word”)
private String fileName;

//@Field(analyzer = “ik_max_word”,searchAnalyzer = “ik_max_word”)
private String fileContent;

//@Field
private String filePath;

private Integer sort;

}

public interface FileRepository extends ElasticsearchRepository<DocFile,String> {
List findDocFileByFileContent(String content);
}

@Override
public void init() {
//原始文件
File file = new File(“D:\Lucene_Document”);
List list = new ArrayList<>();
int count = 0;
for (File f : file.listFiles()) {
count ++;
//文件名
String fileName = f.getName();
//文件内容
String fileContent = TikaUtil.getContext(f);
//文件路径
String path = f.getPath();
DocFile doc= new DocFile();
doc.setId(UUID.randomUUID().toString());
doc.setFileName(fileName);
doc.setFileContent(fileContent);
doc.setFilePath(path);
doc.setSort(count);
list.add(doc);
}
fileRepository.saveAll(list);
}

3.3 数据查询

public List query(String content) {
BoolQueryBuilder builder = QueryBuilders.boolQuery();
//builder下有must、should以及mustNot 相当于sql中的and、or以及not
//设置要查询博客的标题中含有关键字
builder.must(new QueryStringQueryBuilder(content));
//按照博客的评论数的排序是依次降低
FieldSortBuilder sort = SortBuilders.fieldSort(“sort”).order(SortOrder.DESC);
//2.构建查询
NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
//将搜索条件设置到构建中
nativeSearchQueryBuilder.withQuery(builder);
//设置分页(从第一页开始,一页显示10条) 将分页设置到构建中
nativeSearchQueryBuilder.withPageable(new PageRequest(0, 10));
//将排序设置到构建中
nativeSearchQueryBuilder.withSort(sort);
//生产NativeSearchQuery
SearchQuery query = nativeSearchQueryBuilder.build();
//3.执行方法1
Page page = fileRepository.search(query);
//执行方法2:注意,这儿执行的时候还有个方法那就是使用elasticsearchTemplate
//执行方法2的时候需要加上注解
//@Autowired
//private ElasticsearchTemplate elasticsearchTemplate;
// List blogList = elasticsearchTemplate.queryForList(query, DocFile.class);
//4.获取总条数(用于前端分页)
int total = (int) page.getTotalElements();
//5.获取查询到的数据内容(返回给前端)
List list = page.getContent();
return list;
}

@Override
public List search(String content) {
QueryBuilder builder = new QueryStringQueryBuilder(content);
//高亮显示规则
HighlightBuilder highlightBuilder = new HighlightBuilder().field(“fileName”).field(“fileContent”).preTags(“”).postTags(“”);
SearchQuery q = new NativeSearchQueryBuilder()
//.withIndices(“test-file”).withTypes(“file”)
.withSort(SortBuilders.fieldSort(“sort”).order(SortOrder.DESC))
.withHighlightBuilder(highlightBuilder)
.withHighlightFields(new HighlightBuilder.Field(“fileName”),new HighlightBuilder.Field(“fileContent”))
.withQuery(builder).build();
List fileList = elasticsearchTemplate.query(q, response -> {
SearchHits hits = response.getHits();
List bl = new ArrayList<>();
if (hits.getHits().length <= 0) {
return bl;
}
for (SearchHit searchHit : hits) {
DocFile file = new DocFile();
String bookJson = searchHit.getSourceAsString();
if (bookJson == null || “”.equals(bookJson)) {
continue;
}
ObjectMapper mapper = new ObjectMapper();
try {
file = mapper.readValue(bookJson,file.getClass());
} catch (IOException e) {
e.printStackTrace();
}
if (searchHit.getHighlightFields().size() > 0) {
if (searchHit.getHighlightFields().get(“fileName”) != null) {
String highLightName = searchHit.getHighlightFields().get(“fileName”).fragments()[0].toString();
file.setFileName(highLightName);
}
if (searchHit.getHighlightFields().get(“fileContent”) != null) {
String highLightContent = searchHit.getHighlightFields().get(“fileContent”).fragments()[0].toString();
file.setFileContent(highLightContent);
}
}
bl.add(file);
}
return bl;
});
return fileList;
}

controller层:

@RequestMapping(“/search”)
@ResponseBody
public List search(String content) {
return fileService.search(content);
}

页面返回结果:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值