ElasticSearch

ElasticSearch

1.什么是ElasticSearch

Elasticsearch是用Java语言开发的基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。ElasticSearch用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便。

2.为什么实用ElashSearch?

1).ElashSearch扩展性好:分布式,无需人工搭建集群(solr就需要人为配置,使用Zookeeper作为注册中心)。

2).ElashSearch近实时的去索引数据、搜索数据。

3.ElashSearch的原理?

下图是ElasticSearch的索引结构,右边黑蓝色色部分是原始文档,左边黄色部分是逻辑结构,逻辑结构也是为了更好的去描述ElasticSearch的工作原理及去使用物理结构中的索引文件。

ElasticSearch_第1张图片

3.1 索引

3.1.1 倒排索引(Inverted

index):也常被称为反向索引,倒排索引是从关键字到文档的映射(已知关键字求文档)。

1)、将搜索的文档最终以Document方式存储起来。(如下图Doc_1,Doc_2)

2)、将要搜索的文档内容分词,所有不重复的词组成分词列表。(如下图Term)

3)、每个词和docment都有关联。

ElasticSearch_第2张图片

现在,如果我们想搜索 包含quick brown词条的文档:

ElasticSearch_第3张图片

两个文档都匹配,但是第一个文档比第二个匹配度更高。如果我们使用仅计算匹配词条数量的简单 相似性算法 ,那么,我们可以说,对于我们查询的相关性来讲,第一个文档比第二个文档更佳。

3.2 RESTful应用方法

Elasticsearch提供 RESTful Api接口进行索引、搜索,并且支持多种客户端。

下图是es在项目中的应用方式:

ElasticSearch_第4张图片

1)用户在前端搜索关键字

2)项目前端通过http方式请求项目服务端

3)项目服务端通过Http RESTful方式请求ES集群进行搜索

4)ES集群从索引库检索数据。

4 .ElasticSearch 安装

4.1 Windows安装ElasticSearch

4.1.1 安装条件:

1)、jdk必须是jdk1.8.0_131以上版本。

2)、支持tar、zip、rpm等多种安装方式。

3)在windows下开发建议使用ZIP安装方式。

4.1.2下载 ES:

ElasticSearch官网:https://www.elastic.co/cn/

4.1.3 ES是Java开发的应用,解压即安装:

tar -zxvf elasticsearch-6.2.3.tar.gz

4.1.4 ES目录结构

bin 目录:可执行文件包

config 目录:配置相关目录

lib 目录:ES 需要依赖的 jar 包,ES 自开发的 jar 包

modules 目录:功能模块的存放目录,如aggs、reindex、geoip、xpack、eval

plugins 目录:插件目录包,三方插件或自主开发插件

logs 目录:日志文件相关目录

data 目录:在 ES 启动后,会自动创建的目录,内部保存 ES 运行过程中需要保存的数据。

4.1.5 配置文件

ES安装目录config中配置文件如下:

elasticsearch.yml:用于配置Elasticsearch运行参数         

jvm.options:用于配置Elasticsearch JVM设置          

log4j2.properties:用于配置Elasticsearch日志

4.1.5.1  elasticsearch.yml

cluster.name: sxt

node.name: sxt_node_1

network.host: 0.0.0.0

http.port: 9200

transport.tcp.port: 9300

node.master: true

node.data: true

discovery.zen.ping.unicast.hosts:

["0.0.0.0:9300", "0.0.0.0:9301"]

discovery.zen.minimum_master_nodes: 1

bootstrap.memory_lock: false

path.data: D:\ElasticSearch-1\data

path.logs: D:\ElasticSearch-1\logs

http.cors.enabled: true

http.cors.allow-origin:/.*/

常用的配置项如下:

cluster.name:

配置elasticsearch的集群名称,默认是elasticsearch。建议修改成一个有意义的名称。

node.name:

节点名,通常一台物理服务器就是一个节点,es会默认随机指定一个名字,建议指定一个有意义的名称,方便管理

一个或多个节点组成一个cluster集群,集群是一个逻辑的概念,节点是物理概念,后边章节会详细介绍。

path.data:

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

path.logs:

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

bootstrap.memory_lock: true

设置为true可以锁住ES使用的内存,避免内存与swap分区交换数据。

network.host:

设置绑定主机的ip地址,设置为0.0.0.0表示绑定任何ip,允许外网访问,生产环境建议设置为具体的ip。

http.port: 9200

设置对外服务的http端口,默认为9200。

transport.tcp.port: 9300

 集群结点之间通信端口

node.master:

 指定该节点是否有资格被选举成为master结点,默认是true,如果原来的master宕机会重新选举新的master。

node.data:

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

discovery.zen.ping.unicast.hosts:

[“host1:port”, “host2:port”, “…”]

设置集群中master节点的初始列表。

discovery.zen.ping.timeout: 3s

设置ES自动发现节点连接超时的时间,默认为3秒,如果网络延迟高可设置大些。

discovery.zen.minimum_master_nodes:

主结点数量的最少值 ,此值的公式为:(master_eligible_nodes / 2)+ 1 ,比如:有3个符合要求的主结点,那么这里要设置为2。

node.max_local_storage_nodes:

单机允许的最大存储结点数,通常单机启动一个结点建议设置为1,开发环境如果单机启动多个节点可设置大于1.

4.1.5.2 jvm.options

设置最小及最大的JVM堆内存大小:

在jvm.options中设置 -Xms和-Xmx:

1)两个值设置为相等

2)将Xmx 设置为不超过物理内存的一半。

4.1.5.3  properties

日志文件设置,ES使用log4j,注意日志级别的配置。

4.1.6 启动 

进入bin目录,在cmd下运行:elasticsearch.bat

4.1.7 测试: 

 ES 中,只要启动了任意一个 ES 应用,就是启动了一个 ES 的 cluster 集群。默认的 ES集群命名为 elasticsearch。如果启动了多个应用(可以在多个节点或单一节点上启动多个应用),默认的 ES 会自动找集群做加入集群的过程。

浏览器访问:http://127.0.0.1:9200

显示结果:

ElasticSearch_第5张图片

4.2 head插件安装

head插件是ES的一个可视化管理插件,用来监视ES的状态,并通过head客户端和ES服务进行交互,比如创建映射、创建索引等, 从ES6.0开始,head插件支持使得node.js运行。

1)head插件下载:下载地址: https://github.com/mobz/elasticsearch-head

2) 安装

npm install -g cnpm --registry=https://registry.npm.taobao.org

cnpm  install

npm -v

3) 测试 

浏览器访问:http://127.0.0.1:9100/、

ElasticSearch_第6张图片

若打开浏览器调试工具发现报错:  Originnull is not allowed by Access-Control-Allow-Origin.

原因是:head插件作为客户端要连接ES服务(localhost:9200),此时存在跨域问题,elasticsearch默认不允许跨域访问。

解决方案:

在config/elasticsearch.yml后面增加以下参数:

#开启cors跨域访问支持,默认为false

http.cors.enabled: true

#跨域访问允许的域名地址,(允许所有域名)以上使用正则

http.cors.allow-origin: /.*/

4.3安装Kibana

 Kibana是ES提供的一个基于 WEB 的管理控制台, 可以很容易实现高级的数据分析和可视化,以图标的形式展现出来。

 kibana可以用来编辑请求语句的,方便学习操作es的语法。有时在进行编写程序,写到查询语句时,往往我会使用kibana进行书写,然后再粘贴到程序中。(不容易出错)

4.3.1 下载

ElasticSearch官网:https://www.elastic.co/cn/

4.3.2 安装 

在window中安装Kibana很方便,解压即安装

4.3.3 修改配置

vim config/kibana.yml

把以下注释放开,使配置起作用:

       server.port:5601

       server.host:"0.0.0.0" #允许来自远程用户的连接

       elasticsearch.url:http://127.0.0.1:9200# Elasticsearch实例的URL 

       kibana.index:".kibana"#如果没有索引,Kibana 会创建一个新的索引来存储保存的检索,可视化控件以及仪表板

4.3.4 启动

双击bin目录下 kibana.bat

4.3.5 测试

ElasticSearch_第7张图片

5. Elasticsearch相关操作

5.1 index库管理

5.1.1 创建index库

ElasticSearch_第8张图片

number_of_shards - 是表示一个索引库将拆分成多片分别存储不同的结点,提高了ES的处理能力和高可用性

number_of_replicas- 是为每个 primary shard分配的replica shard数,如果只有一台机器,设置为0

效果:

ElasticSearch_第9张图片

5.1.2 修改index

注意:索引一旦创建,primary shard 数量不可变化,可以改变replica shard 数量。

ES 中对 shard 的分布是有要求的,有其内置的特殊算法:

       1、ES 尽可能保证 primary shard平均分布在多个节点上;

       2、Replica shard 会保证不和他的那个 primary shard 分配在同一个节点上;

如过只有一个节点,则此案例执行后索引的状态一定是yellow。

5.1.3删除index

5.1.4 为什么primary shard数量不可变

原因:假如我们的集群在初始化的时候有5个primaryshard,我们往里边加入一个document    id=5,假如hash(5)=23,这时该document 将被加入 (shard=23%5=3)P3这个分片上。如果随后我们给es集群添加一个primaryshard ,此时就有6个primary shard,当我们GET id=5 ,这条数据的时候,es会计算该请求的路由信息找到存储他的 primary shard(shard=23%6=5) ,根据计算结果定位到P5分片上。而我们的数据在P3上。所以es集群无法添加primary shard,但是可以扩展replicas shard。

5.2mapping管理 

 映射,创建映射就是向索引库中创建field(类型、是否索引、是否存储等特性)的过程,下边是document和field与关系数据库的概念的类比:      索引库(indices)--------------------------------Databases数据库              类型(type)-----------------------------Table数据表                  文档(Document)----------------Row 行                            字段(Field)-------------------Columns 列注意:6.0之前的版本有type(类型)概念,type相当于关系数据库的表,ES6.x 版本之后,type概念被弱化ES官方将          在ES7.0版本中彻底删除type。

5.2.1 创建mapping

ElasticSearch_第10张图片


ElasticSearch_第11张图片

5.2.2 查询mappin

ElasticSearch_第12张图片

5.2.3 删除mapping

通过删除索引来删除映射。

5.3 document管理

ES中的文档相当于MySQL数据库表中的记录。

5.3.1 PUT语法

语法:PUT     /index_name/type_name/id{field_name:field_value}

ElasticSearch_第13张图片

结果:

ElasticSearch_第14张图片

  "_index": "test_index",新增的 document 在什么 index 中,

  "_type": "my_type",新增的 document 在 index 中的哪一个 type 中。

  "_id": "1",指定的 id 是多少

  "_version": 1, document的版本是多少,版本从 1 开始递增,每次写操作都会+1

  "result": "created",本次操作的结果,created 创建,updated 修改,deleted 删除

  "_shards": {分片信息

      "total": 2,分片数量只提示primary shard

      "successful": 1,数据 document 一定只存放在 index 中的某一个 primary shard 中

      "failed": 0

  },

  "_seq_no": 0,

  "_primary_term": 1

5.3.2 POST语法

此操作为ES 自动生成 id 的新增 Document 方式。

语法:POST   /index_name/type_name{fieldname:fieldvalue}

ElasticSearch_第15张图片


5..4 查询document

语法:

       GET/index_name/type_name/id

       GET/index_name/type_name/_search?q=field_name:field_value


ElasticSearch_第16张图片

查询结果:

ElasticSearch_第17张图片

{

  "took": 1, #执行的时长。单位毫秒

  "timed_out": false, #是否超时

  "_shards": { # shard相关数据

    "total": 2, #总计多少个shard

    "successful": 2, # 成功返回结果的 shard 数量

    "skipped": 0,

    "failed": 0

  },

  "hits": { #搜索结果相关数据

    "total": 3, # 总计多少数据,符合搜索条件的数据数量

    "max_score": 1, # 最大相关度分数,和搜索条件的匹配度

    "hits": [#具体的搜索结果

      {

        "_index": "java17",#索引名称

        "_type": "course",  #类型名称

        "_id": "1",# id值

        "_score": 1, #匹配度分数,本条数据匹配度分数

        "_source": { #具体的数据内容

          "name": "php从入门到放弃",

          "description": "php是世界上最好的语言",

          "studymodel":  "201001"

        }

      }

    ]

  }

}

5.4 删除Document

6 ES读写原理

documnet routing(数据路由)

当客户端创建document的时候,es需要确定这个document放在该index哪个shard上,这个过程就是document routing。

路由过程:

    路由算法:shard = hash(routing) %number_of_primary_shards

    routing:document的_id,可能是手动指定,也可能是自动生成,决定一个document在哪个shard上

    number_of_primary_shards主分片。

6.1ES document写操作原理

ES增删改的处理流程:增删改的请求一定作用在主分片上。

假如我们es集群有3个node,每个node上一个主分片一个复制分片,

如下图:


ElasticSearch_第18张图片

1)、第一步 客户端发起一个PUT请求,假如该请求被发送到第一个node节点,那么该节点将成为协调节点(coordinating

    node),如图P1所在的节点就是协调节点。他将根据该请求的路由信息计算,该document将被存储到哪个分片。

2)、第二步通过计算发现该document被存储到p0分片,那么就将请求转发到node2节点。

3)、第三步P0根据请求信息创建document,和相应的索引信息,创建完毕后将信息同步到自己的副本节点R0上。

4)、第四步P0和R0将通知我们的协调节点,任务完成情况。

5)、第五部协调节点响应客户端最终的处理结果。

6.2 读操作原理

假如我们es集群有3个node,每个node上一个主分片一个复制分片,

如下图:

ElasticSearch_第19张图片

1)、第一步客户端发送读器请求到协调节点(coordinate node)。

2)、第二步协调节点(coordinate node)根据请求信息对document进行路由计算,将请求转发到对应的node,node2或者node3,此时会使用round-robin随机轮询算法,在primary shard以及其所有replica(副本)中随机选择一个让读请求负载均衡。

3)、第三步相应接收到请求的节点(node2或者node3)将处理结果返回给协调节点(coordinate node)。

4)、第四步协调节点将最终的结果反馈给客户端。

7.   IK分词器

在添加文档时会进行分词,索引中存放的就是一个一个的词(term),当你去搜索时就是拿关键字去匹配词,最终找到词关联的文档。

普通分词器:

会发现分词的效果将“测试”这个词拆分成两个单字“测”和“试”,这是因为当前索引库使用的分词器对中文就是单字分词。

ElasticSearch_第20张图片

7.1. 安装IK分词器 

 使用IK分词器可以实现对中文分词的效果。下载IK分词器:(Github地址:https://github.com/medcl/elasticsearch-analysis-ik)

解压,并将解压的文件拷贝到ES安装目录的plugins下的ik(重命名)目录下

ElasticSearch_第21张图片

7.2.两种分词模式

ik分词器有两种分词模式:ik_max_word和ik_smart模式。

1、ik_max_word

       会将文本做最细粒度的拆分,比如会将“中华人民共和国人民大会堂”拆分为“中华人民共和国、中华人民、中华、华人、人民共和国、人民、共和国、大会堂、大会、会堂等词语。

2、ik_smart

       会做最粗粒度的拆分,比如会将“中华人民共和国人民大会堂”拆分为中华人民共和国、人民大会堂。

ElasticSearch_第22张图片

7.3自定义词库

如果要让分词器支持一些专有词语,可以自定义词库。

iK分词器自带一个main.dic的文件,此文件为扩展词典。

ElasticSearch_第23张图片

也可以上边的目录中新建一个my.dic文件(注意文件格式为utf-8(不要选择utf-8 BOM))

可以在其中自定义词汇:

比如定义:

配置文件中配置my.dic,

ElasticSearch_第24张图片

7.4 field详细介绍


 7.4.1 field的属性介绍


type:  通过type属性指定field的类型。

analyzer:通过analyzer属性指定分词模式。

指定了analyzer是指在索引和搜索都使用ik_max_word,如果单独想定义搜索时使用的分词器则可以通过

search_analyzer属性。

对于ik分词器建议是索引时使用ik_max_word将搜索内容进行细粒度分词,搜索时使用ik_smart提高搜索精确性。

ElasticSearch_第25张图片


index:通过index属性指定是否索引。

默认为index=true,即要进行索引,只有进行索引才可以从索引库搜索到。

但是也有一些内容不需要索引,比如:商品图片地址只被用来展示图片,不进行搜索图片,此时可以将index设置

为false。      删除索引,重新创建映射,将pic的index设置为false,尝试根据pic去搜索,结果搜索不到数据

store:是否在source之外存储,每个文档索引后会在 ES中保存一份原始文档,存放在"_source"中,一般情况下不需要设置

store为true,因为在_source中已经有一份原始文档了。

field索引不存储\ 

如果某个字段内容非常多,业务里面只需要能对该字段进行搜索,最后返回文档id,查看文档内容会再次到mysql或者hbase中取数据,把大字段的内容存在Elasticsearch中只会增大索引,这一点文档数量越大结果越明显,如果一条文档节省几KB,放大到亿万级的量结果也是非常可观的。

如果只想存储某几个字段的原始值到Elasticsearch,可以通过incudes参数来设置,在mapping中的设置如下:

ElasticSearch_第26张图片

同样,可以通过excludes参数排除某些字段:

ElasticSearch_第27张图片

7.5常用field类型

text文本字段

keyword关键字字段

keyword字段为关键字字段,通常搜索keyword是按照整体搜索,所以创建keyword字段的索引时是不进行分词的

date日期类型      

日期类型不用设置分词器,通常日期类型的字段用于排序。

1)format

通过format设置日期格式,多个格式使用双竖线||分隔, 每个格式都会被依次尝试, 直到找到匹配的

ElasticSearch_第28张图片


Numeric类型 

 下图是ES支持的数值类型:

ElasticSearch_第29张图片

1、尽可能选择范围小的数据类型, 字段的长度越短, 索引和搜索的效率越高;

2、对于浮点数尽量用比例因子,比如一个价格字段,单位为元,我们将比例因子设置为100这在ES中会按分存

储,映射如下:

ElasticSearch_第30张图片

由于比例因子为100,如果我们输入的价格是23.45则ES中会将23.45乘以100存储在ES中。

使用比例因子的好处是整型比浮点型更易压缩,节省磁盘空间。

8 Spring Boot整合ElasticSearch

ES提供多种不同的客户端:

1、TransportClient

       ES提供的传统客户端,官方计划8.0版本删除此客户端。

2、RestClient

       RestClient是官方推荐使用的,它包括两种:Java Low Level REST

Client和 Java High

Level REST Client。

ES在6.0之后提供 Java

High Level REST Client,两种客户端官方更推荐使用 Java High Level REST

Client,不过当前它还处于完善中,有些功能还没有。

       本教程准备采用 Java High Level REST Client,如果它有不支持的功能,则使用Java Low Level REST Client

8.1创建项目

ElasticSearch_第31张图片

8.2 修改pom.xml文件


ElasticSearch_第32张图片

8.3 修改application.yml


ElasticSearch_第33张图片

8.4 创建RestHighLevelClient配置类

ElasticSearch_第34张图片

8.5 创建启动类

ElasticSearch_第35张图片

8.6 测试

8.6.1 创建索引库

kinbana:api


ElasticSearch_第36张图片


ElasticSearch_第37张图片

java代码:

ElasticSearch_第38张图片

8.6.2 删除索引库

kinbana:api

java代码:

ElasticSearch_第39张图片


8.6.3 添加文档

kinbana:api

ElasticSearch_第40张图片

java代码:

ElasticSearch_第41张图片


8.6.4 批量添加文档

kinbana:api

java代码:

ElasticSearch_第42张图片

8.6.5 修改文档:

kinbana:api

java代码:


ElasticSearch_第43张图片

8.8.6. 删除文档

kinbana:api

java代码:

ElasticSearch_第44张图片

8.6.7 文档搜索:

8.6.7.1 简单搜索

kibana:api

java代码:

ElasticSearch_第45张图片

8.6.7.2 DSL搜索(  match_all查询)

DSL(Domain Specific Language)是ES提出的基于json的搜索方式,在搜索时传入特定的json格式的数据来完成不同的搜索需求,DSL比URI搜索方式功能强大,在项目中建议使用DSL方式来完成搜索。

kinbana:api

ElasticSearch_第46张图片


ElasticSearch_第47张图片

8.6.7.3 DSL搜索(  Term 查询  )

Term Query为精确查询,在搜索时会整体匹配关键字,不再将关键字分词。

kinbana:api

ElasticSearch_第48张图片

java代码:

ElasticSearch_第49张图片

8.6.7.4 DSL搜索( match查询  ) 

match Query即全文检索,它的搜索方式是先将搜索字符串分词,再使用各各词条从索引中搜索。

query搜索的关键字,对于英文关键字如果有多个单词则中间要用半角逗号分隔,而对于中文关键字中间可以用逗号分隔也可以不用。

operatoror 表示只要有一个词在文档中出现则就符合条件,and表示每个词都在文档中出现则才符合条件。

 kinbana:api 

ElasticSearch_第50张图片

java代码:


ElasticSearch_第51张图片

8.6.7.5 DSL搜索(  multi_match查询   )  

termQuery和matchQuery是在一个field中去匹配,multiQuery是拿关键字去多个Field中匹配。

匹配多个字段时可以提升字段的boost(权重)来提高得分, 如“name^10”表示权重提升10倍,执行查询时name中包括spring关键字的文档排在前边。

kinbana:api

ElasticSearch_第52张图片

java代码:

ElasticSearch_第53张图片


8.6.7.6 DSL搜索( bool查询 )

布尔查询对应于Lucene的BooleanQuery查询,实现将多个查询组合起来。

参数:

       must:表示必须,多个查询条件必须都满足。(通常使用must)

       should:表示或者,多个查询条件只要有一个满足即可。

       must_not:表示非。

kinbana:api:

ElasticSearch_第54张图片

java代码:

ElasticSearch_第55张图片

8.6.7.7 DSL搜索(filter查询)

此操作实际上就是query DSL 的补充语法。过滤的时候,不进行任何的匹配分数计算,相对于 query 来说,filter 相对效率较高。Query 要计算搜索匹配相关度分数。Query更加适合复杂的条件搜索。查询:

kinbana:api


ElasticSearch_第56张图片


java代码:


ElasticSearch_第57张图片

8.7 highlight查询 

 高亮显示。高亮不是搜索条件,是显示逻辑,在搜索的时候,经常需要对条件实现高亮显示。

kinbana:api

ElasticSearch_第58张图片

java代码:

ElasticSearch_第59张图片

9.集群管理

9.1集群结构


ElasticSearch_第60张图片
9.2 

9.2 集群的三个角色

主节点:master节点主要用于集群的管理及索引比如新增节点、分片分配、索引的新增和删除等。

数据节点:data 节点上保存了数据分片,它负责索引和搜索操作。

客户端节点:client节点仅作为负载均衡器不存数据,只是将请求均衡转发到其它节点。


通过下边两项参数来配置节点的功能:

node.master: #是否允许为主节点

node.data: #允许存储数据作为数据节点

node.ingest: #是否允许成为协调节点,

四种组合方式:

master=true,data=true:即是主节点又是数据节点

master=false,data=true:仅是数据节点

master=true,data=false:仅是主节点,不存储数据

master=false,data=false:即不是主节点也不是数据节点,此时可设置ingest为true(默认)表示它是一个客户端。

9.3 创建结点2

ElasticSearch_第61张图片

3、修改elasticsearch-2的elasticsearch.yml内容如下:

cluster.name: sxt

node.name:sxt_node_2

network.host:  0.0.0.0

http.port:9201

transport.tcp.port:9301

node.master:  true

node.data:  true

discovery.zen.ping.unicast.hosts:  ["0.0.0.0:9300", "0.0.0.0:9301"]

discovery.zen.minimum_master_nodes:  1

bootstrap.memory_lock:  false

node.max_local_storage_nodes:  3


path.data:  D:\ElasticSearch-2\data

path.logs:  D:\ElasticSearch-2\logs


http.cors.enabled:  true

http.cors.allow-origin:  /.*/


ElasticSearch_第62张图片

9.4查看集群健康状态

GET _cluster/health

结果:

ElasticSearch_第63张图片

你可能感兴趣的:(ElasticSearch)