• 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

    
    
        org.springframework.boot
        spring-boot-starter-data-elasticsearch
    e
    
    • 1
    • 2
    • 3
    • 4
    • 5

    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 {
    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);
    }

    页面返回结果:

  • 相关阅读:
    ZA7783是一颗将单路MIPI DSI信号转换成单路LVDS/TTL信号的转接芯片
    【蓝桥杯专项】初识0/1背包问题(Java)
    【Java Web】会话管理
    (数据科学学习手札144)使用管道操作符高效书写Python代码
    uniapp 切换WIFI
    【计算机网络】网络层和数据链路层
    MySQL主从复制+读写分离
    项目管理工具——禅道
    tomcat映射本地文件路径
    【Vue】 Vue3 安装说明,适合小白新手
  • 原文地址:https://blog.csdn.net/m0_67401153/article/details/126717094