前言

ElasticSearch 简称 es,是一个开源的高扩展的分布式全文检索引擎。它可以近乎实时的存储、检索数据,且其扩展性很好,ElasticSearch 是企业级应用中较为常见的检索技术。

下面主要记录学习 ElasticSearch7.x 的一些基本结构、在Spring Boot 项目里基本应用的过程,在这里与大家作分享交流。

一、概述

1.1基本认识

ElasticSearch 是基于 Lucene 实现的开源、分布式、RESTful接口的全文搜索引擎。

Elasticsearch 还是一个分布式文档数据库,其中每个字段均是被索引的数据且可被搜索,它能够扩展至数以百计的服务器存储以及处理PB级的数据。

Elasticsearch 可以通过简单的 RESTful 风格 API 来隐藏 Lucene 的复杂性,让搜索变得更加简单。

1.2核心概念

Elasticsearch 的核心概念是 Elasticsearch 搜索的过程,在搜索的过程中,Elasticsearch 的存储过程、数据结构都会有所涉及。

  • 对比关系型数据库
  1. Elasticsearch (集群)中可以包含多个indices(对应库),每个索引中可以包含多个types(对应表),每个types下面又包含多个documents(对应行记录),每个documents中又含有多个fields(对应字段)。
  2. Elasticsearch 中一切数据的格式都是 JSON,一条数据就是一个文档。
  3. 这里 types 的概念已经被逐渐弱化,Elasticsearch 6.X 中,一个 index 下已经只能包含一个type;Elasticsearch 7.X 中 Type 的概念已经被删除了
  4. Elasticsearch 中的索引是一个非常大的文档集合,存储了映射类型的字段和其它设置,被存储在各个分片上。

1.3倒排索引

Elasticsearch 使用一种名为倒排索引的结构进行搜索,一个索引由文档中所有不重复的列表构成,对于每一个词,都有一个包含它的文档列表。

传统数据库的搜索结构一般以id为主,可以一一对应数据库中的所有内容,即 key-value 的形式。

而倒排索引则与之相反,以内容为主,将所有不重复的内容记录按照匹配的程度(阈值)进行展示,即 value-key 的形式。

以下举两个例子来进行说明。

  • 例一:

    在关系型数据库中,数据是按照id的顺序进行约定的,记录的id具有唯一性,方便人们使用id去确定内容,如表2所示:

表2

  • 例二:

    在 ElasticSearch 中使用倒排索引:数据是按照不重复的内容进行约定的,不重复的内容具有唯一性,这样可以快速地找出符合内容的记录,再根据匹配的阈值去进行展示。

    即:id为1和2的行都含有关键字内容Java、id为3和4的行都含有关键字Python。如表3所示:

表3

1.4了解ELK

ELK 是 ElasticSearch、Logstash、Kibana这三大开源框架首字母大写简称。

Logstash 是中央数据流引擎,用于从不同目标(文件/数据存储/MQ)中收集不同的数据格式,经过过滤后支持输送到不同的目的地(文件/MQ/Redis/Elasticsearch/kafka 等)。

Kibana 可以将 ElasticSearch 的数据通过友好的可视化界面展示出来,且提供实时分析的功能。

ELK一般来说是一个日志分析架构技术栈的总称,但实际上 ELK 不仅仅适用于日志分析,它还可以支持任何其它数据分析和收集的场景,日志的分析和收集只是更具有代表性,并非 ELK 的唯一用途。


二、安装(基于 CentOS)

2.1安装声明

  • 适用于 JDK1.8 及以上版本
  • 界面工具 Kibana 应与 ElasticSearch 版本一致
  • ElasticSearch 版本与 Maven 依赖版本对应

2.2 使用 Docker 安装

  • 步骤一:拉取镜像

    docker pull elasticsearch:7.6.1
  • 步骤二:启动镜像

    # 这是一整行命令,不是两行
    docker run --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e ES_JAVA_OPTS="-Xms256m -Xmx256m" -d elasticsearch:7.6.1
  • 步骤三:浏览器访问 http://你的公网ip:9200,即可得到以下json格式的数据,表明已经安装且启动成功,如图1所示:

图1

  • 步骤四:修改配置,解决跨域访问:

    #依次执行以下命令
    docker exec -it elasticsearch /bin/bash #1、进入容器
    cd /usr/share/elasticsearch/config/ #2、cd到config目录
    vi elasticsearch.yml #3、编辑elasticsearch.yml 文件

    添加以下内容到末尾,,保存并退出:

    http.cors.enabled: true
    http.cors.allow-origin: "*"

    退出容器:

    exit

    重启容器:

    docker restart elasticsearch

2.3安装使用 Kibana

Kibana是一个针对 ElasticSearch 的开源分析、可视化平台,用于搜索、查看交互存储在 ElasticSearch 中的数据。

注意事项:Kibana 版本需要和 ElasticSearch 的版本保持一致。

安装步骤如下:

  • 步骤一:拉取镜像

    docker pull kibana:7.6.1
  • 步骤二:启动镜像

    docker run --name kibana --link=elasticsearch:test  -p 5601:5601 -d kibana:7.6.1
  • 步骤三:浏览器打开 http://你的公网ip:5601 进入 Kibana 界面,如图2所示:

图2

2.4安装使用 IK 分词器

在使用中文进行搜索时,我们会对要搜索的信息进行分词:将一段中文分成一个个的词语或者句子,然后将分出的词进行搜索。

默认的中文分词是一个汉字一个词,如:“你好世界”,会被分成:“你”,“好”,“世”,“界”。但这样的分词方式显然并不全面,比如还可以分成:“你好”,“世界”。

ik 分词器就解决了默认分词不全面的问题,可以将中文进行不重复的分词。

ik 分词器提供了两种算法:ik_smart(最少切分)以及 ik_max_word(最细颗粒度划分)。

  • 步骤一:进入容器内部

    docker exec -it elasticsearch /bin/bash
  • 步骤二:在线下载并安装(这是一整行命令,不是两行)

    ./bin/elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v7.6.1/elasticsearch-analysis-ik-7.6.1.zip
  • 步骤三:退出容器并重启:

    # 退出容器
    exit
    # 重启容器
    docker restart elasticsearch
  • 步骤四:点击 kibana 主界面左侧边栏的的 Dev Tools 工具,输入测试命令,效果如图3所示:

图3


三、RESTful 操作

ElasticSearch 支持使用 RESTful 风格来进行一系列操作,使用的是标准的 HTTP 方法,比如 GET、PUT、POST 和 DELETE。

3.1索引操作

以下关于索引的操作,可以在 postman 或者 Kibana 上操作。postman 要带上你的公网ip:端口,kibana 要注明是 GET 或者 PUT,其它操作都是一样的。

  1. 创建索引
{
"acknowledged": true,
"shards_acknowledged": true,
"index": "article"
}
  1. 查看单个索引信息
{
"article": {
"aliases": {},
"mappings": {},
"settings": {
"index": {
"creation_date": "1700029085972",
"number_of_shards": "1",
"number_of_replicas": "1",
"uuid": "4rVnVk22SnGURHF5tCvPkQ",
"version": {
"created": "7060199"
},
"provided_name": "article"
}
}
}
}
  1. 查看所有索引信息
health status index                    uuid                   pri rep docs.count docs.deleted store.size pri.store.size
green open .security-7 2xUWUkq1Soyg0ydewEKrew 1 0 42 0 109.1kb 109.1kb
green open .kibana_task_manager_1 Q53d13THSeKzauDGgDGv2Q 1 0 2 0 26.2kb 26.2kb
green open .apm-agent-configuration cbMuzKXGQReJyEa9CDCZlw 1 0 0 0 283b 283b
green open .kibana_1 hShl-bvbTpqm9Y9ih-sO5w 1 0 13 4 32.8kb 32.8kb
yellow open article 4rVnVk22SnGURHF5tCvPkQ 1 1 0 0 283b 283b
  1. 删除索引
{
"acknowledged": true
}

3.2文档操作

documents 可以看作是数据库中的一行行记录,数据格式为 JSON 格式。由于没有了表的概念,所以看作所有的 documents 都是直接存在 index 里的。

以下使用可视化工具 Kibana 来进行操作。

  1. 新增文档数据
  1. 更新文档数据

    和新增文档一样,输入语句,如果请求体的值有变化,会将原有的数据内容覆盖:

  1. 查看单个文档
  1. 查看所有文档
  1. 简单条件查询

    • match 匹配类型查询,会先对查询条件进行分词,然后进行查询:
    # 查看该索引内所有数据,条件是匹配对 title 分词后包含”文章“的 documents
    GET /article/_search
    {
    "query": {
    "match":{
    "title":"文章"
    }
    }
    }
    • multi_match 与 match 类似,不同的是它可以在多个字段中查询:
    # 查看该索引内所有数据,条件是对输入的 query 内容使用 ik_max_word 分词,然后分别对 title、content 字段的内容做匹配
    GET /article/_search
    {
    "query": {
    "multi_match":{
    "query": "文章的",
    "fields": ["title","content"],
    "analyzer": "ik_max_word"
    }
    }
    }

    上述的简单条件查询操作在企业级应用开发中一般不会单独使用,更多地还是结合复杂查询实现业务,对于复杂查询的操作在第四章会详细介绍。

  2. 删除 documents 数据

    一般删除数据都是根据文档的唯一性标识进行删除。实际操作时,也可以根据条件对多条数据进行删除。

    # 根据条件删除,即删除可以匹配到 favourNum 内容为 6 的所有文档
    POST /article/_delete_by_query
    {
    "query":{
    "match":{
    "favourNum":6
    }
    }
    }

3.3映射操作

我们知道,ES 的索引相当于传统数据库中的 Database,那么建索引(index)中的映射就类似于数据库(Database)中的表结构(Table)。

设计表需要设置:字段名、类型、长度、约束等,索引也一样,需要知道这个文档中有哪些字段,每个字段有哪些约束信息,这个过程就是创建映射(mapping)。

其实在 Spring Boot 中新建 ES 实体类的时候,使用 @Document 注解、@Field 注解就可以对字段做映射,详情可以看我的另一篇关于 ES 的博文。


四、复杂查询详解

ElasticSearch 引擎首先分析需要查询的 query 参数内容,未提前声明不分词的情况下,都会根据分词器规则进行分词,然后根据查询条件进行结果匹配返回。

4.1关键字介绍

4.1.1通用概念
  • Query :将需要查询的 JSON 参数体进行包裹,声明这是一条查询语句,通常其字段类型为 String 字符串。
  • keyword :keyword 代表一种关键词的分词类型,表明该字段的值不会被分词器所分词。
  • score:字段内容与词条的匹配程度,分数越高表明匹配度越高,就越符合查询结果,默认也会按照分数值排序返回结果。
  • hits:对应 Java 代码中的 hit 对象,包含了索引和文档信息,包括查询结果总数,查询出来的 documents 内容(一串 JSON)、分数(score)等。
  • source:需要展示的内容字段,默认是展示索引的所有字段,也可以自定义条件指定需要展示的字段。
4.1.2布尔查询(BoolQueryBuilder)
  • must :在 must 中的内容都是必须执行的内容,在 must 中可以创建多条语句;多条语句需同时满足条件才能执行,作用相当于 SQL 语句中的 AND 。
  • should :在 should 关键字里的内容只要满足其中一项就可以执行,作用相当于 SQL 语句中的 OR 。
  • must_not :类似于 Java 中的 != 作用,即展示查询内容之外的内容。
  • filter:根据指定的条件来过滤掉不符合要求的文档,倾向于”当前文档和查询的条件是不是相符“,且不会对结果做相关性得分计算;filter 子句内还可包含 bool 子句,以实现更复杂的逻辑。
  • minimum_should_match:用来控制查询精度,如果 bool 语句有至少一个 should 子语句则默认值为1,表示 should 语句中的条件起码要满足一个;如果 bool 语句中包含有 must 或 filter 子句,则其默认值为0,即表示 should 子句可以不满足任何条件。

小结:BoolQueryBuilder 的子句只有 must、should、must_not 和 filter 这4种,其中只有 must 和 should 子句会计算相关性评分。

4.1.3基本查询(QueryBuilders)
  • match :作用是对某个字段的匹配查询,首先输入的参数会经过分词器的分词,分词后的结果与字段的值进行匹配,最后再执行 match 查询。

    默认情况下:字段内容必须完整地匹配到任意一个词条(分词后),才会有返回结果。如果需要查询的词有多个,可以用空格隔开。

  • multi_match:在 match 的基础进行了一些加强,不同的是它可以在多个字段中查询,将符合的结果返回。

  • match_all:没有任何条件,是一种检索所有数据的全量查询,一般配合使用分页使用。

  • match_phrase:会对输入的查询参数做分词,但是需要结果中也包含所有的分词,并且顺序要求一致。这个条件比较苛刻,一般的业务可能用不到。

  • term:精确查询关键字,使用 term 时首先不会对需要查询的输入参数进行分词,只有精确地匹配到一模一样的内容才会返回结果。

  • terms:与 term 类似,但它允许指定多个值进行匹配。如果这个字段包含了指定值中的任何一个值,那么这个文档就满足条件,作用类似于 MySQL的 in。

  • includes:默认情况 ES 会返回 _source 里的全部字段,includes 可以用来指定想要显示的字段;

  • excludes:是 includes 的取反,可以用来指定不想显示的字段。

  • range:查询在指定区间范围内的数字或者时间,使用 gt(大于)、gte(大于等于)、lt(小于)和 lte (小于等于)来作为条件。

  • fuzzy:模糊查询,要与 match 区别开来,fuzzy 会在指定的编辑距离内创建一组搜索词的所有可能的变体或扩展,通过 fuzziness 修改编辑距离。

  • highlight :进行关键字搜索时,搜索出的内容中的关键字部分会显示不同的颜色;可以配合使用 match 查询时,加上一个 highlight 属性。

4.1.4分页查询(PageRequest)
  • PageRequest

    PageRequest pageRequest = PageRequest.of((int) current, (int) pageSize);
4.1.5排序(SortBuilder)
  • sort:按照指定的字段进行排序,并且通过 order 指定排序的方式:desc 降序,asc 升序;也可多字段排序,先排字段1,如字段1相等,再根据字段2排。
4.1.6聚合查询
  • 聚合允许对 ES 的文档进行统计分析,类似与关系型数据库中的 Group By,它要更强大和灵活,当然还有很多其它的聚合,例如取最大值、平均值等。

五、文章小结

ES 的核心是索引和其结构,不同与B+树,这是检索速度快的根本原因,同时其 Json 结构也适合放入大量的文档内容。

至于其索引和文档 API 的操作,可以参考官方文档的例子在 postman 或者 Kibana上操作,直至熟练为止。其查询语句是应用的核心,常用语句和语法的学习,可以结合 Spring Boot 项目来进一步实践,从参数判断、查询构造、数据同步等方面探究,相信读者会有不一样的收获。

最后,本文的分享到此结束了,如有错误和不足,期待大家的指正和交流。

参考文档:

  1. ElasticSearch 官方查询 API 文档:https://www.elastic.co/guide/en/elasticsearch/reference/current/search.html

  2. 推荐阅读:

【主流技术】浅析 ElasticSearch7.x 的基本结构及应用(一)的更多相关文章

  1. 【收藏用】--切勿转载Java处理XML的三种主流技术及介绍

    原帖地址 : http://www.ibm.com/developerworks/cn/xml/dm-1208gub/ XML (eXtensible Markup Language) 意为可扩展标记 ...

  2. [转]STUN和TURN技术浅析

    [转]STUN和TURN技术浅析 http://www.h3c.com.cn/MiniSite/Technology_Circle/Net_Reptile/The_Five/Home/Catalog/ ...

  3. Java 处理 XML 的三种主流技术及介绍

    Java 处理 XML 的三种主流技术及介绍 原文地址:https://www.ibm.com/developerworks/cn/xml/dm-1208gub/ XML (eXtensible Ma ...

  4. SafeSEH原理及绕过技术浅析

    SafeSEH原理及绕过技术浅析 作者:magictong 时间:2012年3月16日星期五 摘要:主要介绍SafeSEH的基本原理和SafeSEH的绕过技术,重点在原理介绍. 关键词:SafeSEH ...

  5. 爬虫技术浅析 | WooYun知识库

    爬虫技术浅析 | WooYun知识库 爬虫技术浅析 好房通ERP | 房产中介软件最高水准领导者 undefined

  6. 爬虫技术浅析 | z7y Blog

    爬虫技术浅析 | z7y Blog 爬虫技术浅析

  7. 手机微硬盘读取速度>50MB/s eMMC技术浅析

    转载:http://mobile.zol.com.cn/296/2968659_all.html#p2968659 手机微硬盘读取速度>50MB/s 在开始今天的话题之前,请大家随笔者一起时光倒 ...

  8. NB-IoT将成为未来5G物联网主流技术

    日前,我国完成了IMT-2020(5G)候选技术方案的完整提交.据悉,在提交的方案中,NB-IoT技术被正式纳入5G候选技术集合,预计2020年6月ITU将正式宣布5G技术方案的诞生.而NB-IoT也 ...

  9. 在线直播: .NET与物联网主流技术探秘 初识IoT!

    DNT精英论坛暨.NET北京俱乐部是由资深.NET专家和社区活跃分子发起的技术论坛,以“分享.成长.合作.共赢”为原则,致力于打造一个领先的技术分享平台和成长交流生态.本次活动由aelf赞助支持,刘洪 ...

  10. java编译期优化与执行期优化技术浅析

    java语言的"编译期"是一段不确定的过程.由于它可能指的是前端编译器把java文件转变成class字节码文件的过程,也可能指的是虚拟机后端执行期间编译器(JIT)把字节码转变成机 ...

随机推荐

  1. PPT 如何做出高大上的表格

    字不如表.表不如图 如何做 https://www.bilibili.com/video/BV1ha411g7f5?p=17

  2. 柔性上肢康复机器人研究中的VR技术

    上肢康复机器人用于对脑卒中患者进行上肢康复治疗,能够维持和扩大患者关节活动度.增强肌肉力和协调性,以防止肌肉萎缩.关节痉挛等各类症状的出现,最终重建肢体功能,以便回归正常生活.现有的上肢康复机器人训练 ...

  3. Docker--镜像&&容器基本操作

    1 基础镜像 BusyBox 一个极简版的Linux系统 集成了100多种常用Linux命令 大小不到2MB 适用于简单测试场景 Alpine 一个面向安全的轻型Linux发行版系统 比BusyBox ...

  4. 【调试】kdump原理及其使用方法

    kdump机制 简介 Kdump是在系统崩溃.死锁或死机时用来转储内存运行参数的一个工具和服务,是一种新的crash dump捕获机制,用来捕获kernel crash(内核崩溃)的时候产生的cras ...

  5. freeswitch配置SBC的方案

    概述 freeswitch 是一款好用的开源软交换平台. 但是,fs不是专为SBC而开发的,所以需要做一些定制化的配置和开发. 本文主要介绍如何利用fs的基本功能配置一个简单的SBC方案,满足一般化需 ...

  6. 1. 常用的一些系统性能排查linux命令

    目录 一.CPU 1.1 top命令--CPU性能 1.2 负载 -- CPU 任务排队情况 1.3 vmstat -- CPU 繁忙程度 二.内存 2.1 top命令 三.IO 3.1 iostat ...

  7. [转帖]AES算法(五)GCM工作模式

    https://zhuanlan.zhihu.com/p/376692295 在以前介绍的基本工作模式中,ECB.CFB.OFB 三种模式可以解决 ECB 模式中相同明文生成相同密文的缺陷,CTR 又 ...

  8. [转帖]关于Nacos默认token.secret.key及server.identity风险说明及解决方案公告

    https://nacos.io/zh-cn/blog/announcement-token-secret-key.html 近期Nacos社区收到关于Nacos鉴权功能通过token.secret. ...

  9. [转帖]50年来Intel CPU变化有多大?频率从0.75MHz提升到5.2GHz

    https://m.baidu.com/bh/m/detail/ar_9297450181050583423?data_from=lemon 今天(11月15日)是Intel推出4004处理器50周年 ...

  10. Nginx的再学习

    第一部分 Nginx的版本 Nginx官网提供了三个类型的版本 Mainline version:Mainline 是 Nginx 目前主力在做的版本,可以说是开发版 Stable version:最 ...