Elastic search入门到集群实战操作详解(原生API操作、springboot整合操作)-step1

Elastic search入门到集群实战操作详解(原生API操作、springboot整合操作)-step2

https://blog.csdn.net/qq_45441466/article/details/120116751

接下来所需的资料,也可自行下载。

链接:https://pan.baidu.com/s/1F_daKD1DJ09bhiqryQkgXA 
提取码:qlws 

1 Elastic search介绍和安装

Elasticsearch是一个需要安装配置的软件。

ELK技术栈说明:

Elastic有一条完整的产品线:Elasticsearch、Logstash、Kibana等,前面说的三个就是大家常说的ELK 技术栈(开源实时日志分析平台)。

Elastic search入门到集群实战操作详解(原生API操作、springboot整合操作)-step1_第1张图片

 Logstash 的作用就是一个数据收集器,将各种格式各种渠道的数据通过它收集解析之后格式化输出到 Elasticsearch ,最后再由 Kibana 提供的比较友好的 Web 界面进行汇总、分析、搜索。

ELK 内部实际就是个管道结构,数据从 Logstash 到 Elasticsearch 再到 Kibana 做可视化展示。这三个 组件各自也可以单独使用,比如 Logstash 不仅可以将数据输出到Elasticsearch ,也可以到数据库、缓 存等

1.1.简介

1.1.1Elastic

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

Elastic有一条完整的产品线:Elasticsearch、Logstash、Kibana等,前面说的三个就是大家常说的ELK 技术栈。

1.1.2.Elasticsearch

Elasticsearch官网:https://www.elastic.co/cn/products/elasticsearch

Elastic search入门到集群实战操作详解(原生API操作、springboot整合操作)-step1_第2张图片

功能:

分布式的搜索引擎:百度、Google、站内搜索

全文检索:提供模糊搜索等自动度很高的查询方式,并进行相关性排名,高亮等功能

数据分析引擎(分组聚合):电商网站—一周内手机销量Top10

对海量数据进行近乎实时处理:水平扩展,每秒钟可处理海量事件,同时能够自动管理索引和查询在集 群中的分布方式,以实现极其流畅的操作。

如上所述,Elasticsearch具备以下特点:

        高速、扩展性、最相关的搜索结果

  • 分布式:节点对外表现对等,每个节点都可以作为入门,加入节点自动负载均衡
  • JSON:输入输出格式是JSON
  • Restful风格,一切API都遵循Rest原则,容易上手
  • 近实时搜索,数据更新在Elasticsearch中几乎是完全同步的,数据检索近乎实时
  • 安装方便:没有其它依赖,下载后安装很方便,简单修改几个参数就可以搭建集群
  • 支持超大数据:可以扩展到PB级别的结构化和非结构化数据

1.1.3.版本

目前Elasticsearch最新的版本是7.x,企业内目前用的比较多是6.x,我们以6.2.4进行讲解,需要JDK1.8 及以上

Elastic search入门到集群实战操作详解(原生API操作、springboot整合操作)-step1_第3张图片

1.2.安装和配置

为了快速看到效果我们直接在本地window下安装Elasticsearch。环境要求:JDK8及以上版本

第一步:把今天资料文件夹中准备好的软件放到一个没有中文没有空格的位置,解压即可

Elastic search入门到集群实战操作详解(原生API操作、springboot整合操作)-step1_第4张图片

 第二步:修改配置文件

1、修改索引数据和日志数据存储的路径

Elastic search入门到集群实战操作详解(原生API操作、springboot整合操作)-step1_第5张图片

 第33行和37行,修改完记得把注释打开
 

path.data: d:\class\es\data
#
# Path to log files:
#
path.logs: d:\class\es\log

第三步:进入bin目录中直接双击 图下的命令文件。

如果启动失败需要修改虚拟机内存的大小

找到jvm.options文件 如图修改
Xms 是指设定程序启动时占用内存大小。一般来讲,大点,程序会启动的快一点,但是也可能会 导致机器暂时间变慢。

Xmx 是指设定程序运行期间最大可占用的内存大小。如果程序运行需要占用更多的内存,超出了 这个设置值,就会抛出OutOfMemory异常。

Elastic search入门到集群实战操作详解(原生API操作、springboot整合操作)-step1_第6张图片

 1.3.访问

可以看到绑定了两个端口:

9300:集群节点间通讯接口,接收tcp协议

9200:客户端访问接口,接收Http协议

我们在浏览器中访问:http://127.0.0.1:9200

Elastic search入门到集群实战操作详解(原生API操作、springboot整合操作)-step1_第7张图片

1.4.安装kibana

1.4.1.什么是Kibana

Elastic search入门到集群实战操作详解(原生API操作、springboot整合操作)-step1_第8张图片

 Kibana是一个基于Node.js的Elasticsearch索引库数据统计工具,可以利用Elasticsearch的聚合功能, 生成各种图表,如柱形图,线状图,饼图等。

而且还提供了操作Elasticsearch索引数据的控制台,并且提供了一定的API提示,非常有利于我们学习 Elasticsearch的语法。

1.4.2.安装

因为Kibana依赖于node,需要在windows下先安装Node.js;

一路下一步即可安装成功,然后在任意DOS窗口输入名:

node -v

可以查看到node版本就成功了,如下:

 然后安装kibana,最新版本与elasticsearch保持一致,也是6.2.4,解压即可

 1.4.3.配置运行

进入安装目录下的config目录,修改kibana.yml文件的第21行(注释放开即可):

修改elasticsearch服务器的地址:

elasticsearch.url: "http://127.0.0.1:9200"

进入安装目录下的bin目录:

Elastic search入门到集群实战操作详解(原生API操作、springboot整合操作)-step1_第9张图片

发现kibana的监听端口是5601 我们访问:http://127.0.0.1:5601

1.4.4.控制台

选择左侧的DevTools菜单,即可进入控制台页面:

 Elastic search入门到集群实战操作详解(原生API操作、springboot整合操作)-step1_第10张图片

 Elastic search入门到集群实战操作详解(原生API操作、springboot整合操作)-step1_第11张图片

1.5.安装ik分词器

Lucene的IK分词器早在2012年已经没有维护了,现在我们要使用的是在其基础上维护升级的版本,并 且开发为Elasticsearch的集成插件了,与Elasticsearch一起维护升级,版本也保持一致 https://github.com/medcl/elasticsearch-analysis-ik

1.5.1.安装

1. 解压elasticsearch-analysis-ik-6.2.4.zip后,将解压后的文件夹拷贝到elasticsearch-6.2.4\plugins 下,并重命名文件夹为ik

2. 重新启动ElasticSearch,即可加载IK分词器

Elastic search入门到集群实战操作详解(原生API操作、springboot整合操作)-step1_第12张图片

 1.5.2.测试

在kibana控制台输入下面的请求:

GET /_analyze
{
  "analyzer": "ik_max_word",
  "text": "我是中国人"
}

1.6 安装Head插件

1.6.1 elasticsearch-head 简介

elasticsearch-head 简介

elasticsearch-head是一个界面化的集群操作和管理工具,可以对集群进行傻瓜式操作。你可以通过 插件把它集成到es(首选方式),也可以安装成一个独立webapp。

es-head主要有三个方面的操作:

        1. 显示集群的拓扑,并且能够执行索引和节点级别操作

        2. 搜索接口能够查询集群中原始json或表格格式的检索数据

        3. 能够快速访问并显示集群的状态

官方的文档: https://github.com/mobz/elasticsearch-head

Elastic search入门到集群实战操作详解(原生API操作、springboot整合操作)-step1_第13张图片

根据github的文档,操作后 打开localhost:9100即可。

2.使用kibana对索引库操作

2.1.基本概念

2.1.1.节点、集群、分片及副本

1、节点 (node)

一个节点是一个Elasticsearch的实例。 在服务器上启动Elasticsearch之后,就拥有了一个节点。如果在另一台服务器上启动Elasticsearch,这 就是另一个节点。甚至可以通过启动多个Elasticsearch进程,在同一台服务器上拥有多个节点。

2、集群(cluster)

多个协同工作的Elasticsearch节点的集合被称为集群。 在多节点的集群上,同样的数据可以在多台服务器上传播。这有助于性能。这同样有助于稳定性,如果 每个分片至少有一个副本分片,那么任何一个节点宕机后,Elasticsearch依然可以进行服务,返回所有 数据。

但是它也有缺点:必须确定节点之间能够足够快速地通信,并且不会产生脑裂效应(集群的2个部分不 能彼此交流,都认为对方宕机了)。

3、分片 (shard)

索引可能会存储大量数据,这些数据可能超过单个节点的硬件限制。例如,十亿个文档的单个索引占用 了1TB的磁盘空间,可能不适合单个节点的磁盘,或者可能太慢而无法单独满足来自单个节点的搜索请 求。

为了解决此问题,Elasticsearch提供了将索引细分为多个碎片的功能。创建索引时,只需定义所需的分 片数量即可。每个分片本身就是一个功能齐全且独立的“索引”,可以托管在群集中的任何节点上。

分片很重要,主要有两个原因:

  • 它允许您水平分割/缩放内容量
  • 它允许您跨碎片(可能在多个节点上)分布和并行化操作,从而提高性能/吞吐量

分片如何分布以及其文档如何聚合回到搜索请求中的机制完全由Elasticsearch管理,并且对您作为用户 是透明的。

在随时可能发生故障的网络/云环境中,非常有用,强烈建议您使用故障转移机制,以防碎片/节点因某 种原因脱机或消失。为此,Elasticsearch允许您将索引分片的一个或多个副本制作为所谓的副本分片 (简称副本)。

4、副本(replica

分片处理允许用户推送超过单机容量的数据至Elasticsearch集群。副本则解决了访问压力过大时单机无 法处理所有请求的问题。

分片可以是主分片,也可以是副本分片,其中副本分片是主分片的完整副本。副本分片用于搜索,或者 是在原有的主分片丢失后成为新的主分片。

注意:可以在任何时候改变每个分片的副本分片的数量,因为副本分片总是可以被创建和移除的。这并 不适用于索引划分为主分片的数量,在创建索引之前,必须决定主分片的数量。过少的分片将限制可扩 展性,但是过多的分片会影响性能。默认设置的5份是一个不错的开始。

1.1.2 文档、类型、索引及映射

1、文档 (document)

Elasticsearch是面向文档的,这意味着索引和搜索数据的最小单位是文档。

在Elasticsearch中文档有几个重要的属性。

  • 它是自我包含的。一篇文档同时包含字段和它们的取值。
  • 它可以是层次的。文档中还包含新的文档,字段还可以包含其他字段和取值。例如,“location”字 段可以同时包含“city”和“street“两个字段。
  • 它拥有灵活的结构。文档不依赖于预先定义的模式。并非所有的文档都需要拥有相同的字段,它们 不受限于同一个模式。

2、类型 (type)

类型是文档的逻辑容器,类似于表格是行的容器。在不同的类型中,最好放入不同结构的文档。例如, 可以用一个类型定义聚会时的分组,而另一个类型定义人们参加的活动。

3、索引 (index)

索引是映射类型的容器。一个Elasticsearch索引是独立的大量的文档集合。 每个索引存储在磁盘上的同 组文件中,索引存储了所有映射类型的字段,还有一些设置。

4、映射(mapping)

所有文档在写入索引前都将被分析,用户可以设置一些参数,决定如何将输入文本分割为词条,哪些词 条应该被过滤掉,或哪些附加处理有必要被调用(比如移除HTML标签)。这就是映射扮演的角色:存 储分析链所需的所有信息。

Elasticsearch也是基于Lucene的全文检索库,本质也是存储数据,很多概念与MySQL类似的。

对比关系:

        Elastic search入门到集群实战操作详解(原生API操作、springboot整合操作)-step1_第14张图片

 详细说明:

索引库(indices) indices是index的复数,代表许多的索引,
概念 说明
类型(type) 类型是模拟mysql中的table概念,一个索引库下可以有不同类型的索引(目前 6.X以后的版本只能有一个类型),类似数据库中的表概念。数据库表中有表 结构,也就是表中每个字段的约束信息;索引库的类型中对应表结构的叫做 映 射(mapping) ,用来定义每个字段的约束。
文档 (document) 存入索引库原始的数据。比如每一条商品信息,就是一个文档
字段(field) 文档中的属性
映射配置 (mappings) 字段的数据类型、属性、是否索引、是否存储等特性

2.2.创建索引库

2.2.1.语法

Elasticsearch采用Rest风格API,因此其API就是一次http请求,你可以用任何工具发起http请求

创建索引的请求格式:

  • 请求方式:PUT
  • 请求路径:/索引库名
  • 请求参数:json格式:

 { "settings": { "属性名": "属性值" } }

settings:就是索引库设置,其中可以定义索引库的各种属性,目前我们可以不设置,都走默认。

2.2.3.使用kibana创建

kibana的控制台,可以对http请求进行简化,示例:

PUT /lp

相当于是省去了elasticsearch的服务器地址 而且还有语法提示,非常舒服。

2.3.查看索引库

 Get请求可以帮我们查看索引信息,格式:

GET /索引库名

2.4.删除索引库

删除索引使用DELETE请求

DELETE /索引库名

3.使用kibana对类型及映射操作

有了 索引库 ,等于有了数据库中的 database 。接下来就需要索引库中的 类型 了,也就是数据库中的 。创建数据库表需要设置字段约束,索引库也一样,在创建索引库的类型时,需要知道这个类型下 有哪些字段,每个字段有哪些约束信息,这就叫做 字段映射(mapping) 注意:Elasticsearch7.x取消了索引type类型的设置,不允许指定类型,默认为_doc,但字段仍然是有 的,我们需要设置字段的约束信息,叫做字段映射(mapping)

3.1.创建字段映射

语法:请求方式依然是PUT

PUT /索引库名/_mapping/typeName
{
        "properties": {
           "字段名": {
             "type": "类型",
             "index": true,
             "store": true,
             "analyzer": "分词器"
            }
   }
}

Elastic search入门到集群实战操作详解(原生API操作、springboot整合操作)-step1_第15张图片

 类型名称:就是前面将的type的概念,类似于数据库中的表

字段名:任意填写,下面指定许多属性,例如:

  • type:类型,可以是text、keyword、long、short、date、integer、object等
  • index:是否索引,默认为true
  • store:是否存储,默认为false
  • analyzer:分词器,这里的 ik_max_word 即使用ik分词器

示例

发起请求:

PUT /lgt/_mapping/goods
{
  "properties": {
    "title": {
      "type": "text",
      "analyzer": "ik_max_word"
    },
    "images": {
      "type": "keyword",
      "index": "false"
    },
    "price": {
      "type": "float"
    }
  }
}

相应结果:

{
  "acknowledged": true
}

上述案例中,就给 lgt 这个索引库添加了一个名为 goods 的类型,并且在类型中设置了3个字段:

  • title:商品标题
  • images:商品图片
  • price:商品价格

3.2.查看映射关系

语法

GET /索引库名/_mapping

查看某个索引库中的所有类型的映射。如果要查看某个类型映射,可以再路径后面跟上类型名称。即:

GET /索引库名/_mapping/类型名

示例

GET /lgt/_mapping/goods

响应

{
  "lgt": {
    "mappings": {
      "goods": {
        "properties": {
          "images": {
            "type": "keyword",
            "index": false
          },
          "price": {
            "type": "float"
          },
          "title": {
            "type": "text",
            "analyzer": "ik_max_word"
          }
        }
      }
    }
  }
}

3.3.映射属性详解

1)type

Elasticsearch中支持的数据类型非常丰富:

Elastic search入门到集群实战操作详解(原生API操作、springboot整合操作)-step1_第16张图片

一级分类 二级分类 具体类型 使用
核 心 类 型 字符 串类 型 text,keyword 结构化搜索,全文文本搜索、聚合、排 序等
整数 类型 integer,long,short,byte 字段的长度越短,索引和搜索的效率越 高。
浮点 类型 double,float,half_float,scaled_float
逻辑 类型 boolean
日期 类型 date
范围 类型 range
二进 制类 型 binary 该 binary 类型接受二进制值作为 Base64编码的字符串。该字段默认情 况下不存储(store),并且不可搜索
复 合 类 型 数组 类型 array
对象 类型 object 用于单个JSON对象
嵌套 类型 nested nested
地 理 类 型 地理 坐标 类型 geo_point 纬度/经度积分
地理 地图 geo_shape 用于多边形等复杂形状
特 殊 类 型 IP类 型 ip 用于IPv4和IPv6地址
范围 类型 completion 提供自动完成建议
令牌 计数 类型 token_count 计算字符串中令牌的数量

我们说几个关键的:

String类型,又分两种:

        text:使用文本数据类型的字段,它们会被分词,文本字段不用于排序,很少用于聚合,如 文章标题、正文。

        keyword:关键字数据类型,用于索引结构化内容的字段,不会被分词,必须完整匹配的内 容,如邮箱,身份证号。支持聚合

这两种类型都是比较常用的,但有的时候,对于一个字符串字段,我们可能希望他两种都支持,此 时,可以利用其多字段特性

Numerical:数值类型,分两类

  • 基本数据类型:long、interger、short、byte、double、float、half_float
  • double 双精度64位
  • float 单精度32位
  •  half_float 半精度16位
  •  浮点数的高精度类型:scaled_float
    带有缩放因子的缩放类型浮点数,依靠一个 long 数字类型通过一个固定的( double 类 型)缩放因数进行缩放.
    需要指定一个精度因子,比如10或100。elasticsearch会把真实值乘以这个因子后存 储,取出时再还原

Date:日期类型

elasticsearch可以对日期格式化为字符串存储,但是建议我们存储为毫秒值,存储为long,节省 空间。

Array:数组类型

  • 进行匹配时,任意一个元素满足,都认为满足
  • 排序时,如果升序则用数组中的最小值来排序,如果降序则用数组中的最大值来排序

字符串数组:["one", "two"]

整数数组:[1,2]

数组的数组:[1, [2, 3]],等价于[1,2,3]

对象数组:[ { "name": "Mary", "age": 12 }, { "name": "John", "age": 10 }]

Object:对象

JSON文档本质上是分层的:文档包含内部对象,内部对象本身还包含内部对象。

Elastic search入门到集群实战操作详解(原生API操作、springboot整合操作)-step1_第17张图片

 如果存储到索引库的是对象类型,例如上面的manager,会把girl编程两个字段:manager.name和manager.age

ip地址

PUT my_index
{
  "mappings": {
    "_doc": {
      "properties": {
        "ip_addr": {
          "type": "ip"
          }
        }
      }
    }
}
PUT my_index/_doc/1
{
  "ip_addr": "192.168.1.1"
}
GET my_index/_search
{
  "query": {
    "term": {
      "ip_addr": "192.168.0.0/16"
    }
  }
}

2)index

index影响字段的索引情况。

         true:字段会被索引,则可以用来进行搜索过滤。默认值就是true,只有当某一个字段的index值 设置为true时,检索ES才可以作为条件去检索。

        false:字段不会被索引,不能用来搜索

index的默认值就是true,也就是说你不进行任何配置,所有字段都会被索引。

但是有些字段是我们不希望被索引的,比如商品的图片信息(URL),就需要手动设置index为false。

3)store

是否将数据进行额外存储。

在学习lucene时,我们知道如果一个字段的store设置为false,那么在文档列表中就不会有这个字段的 值,用户的搜索结果中不会显示出来。

但是在Elasticsearch中,即便store设置为false,也可以搜索到结果。

原因是Elasticsearch在创建文档索引时,会将文档中的原始数据备份,保存到一个叫做 _source 的属性 中。而且我们可以通过过滤 _source 来选择哪些要显示,哪些不显示。

而如果设置store为true,就会在 _source 以外额外存储一份数据,多余,因此一般我们都会将store设 置为false,事实上,store的默认值就是false。

在某些情况下,这对 store 某个领域可能是有意义的。例如,如果您的文档包含一个 title ,一个 date 和一个非常大的 content 字段,则可能只想检索the title 和the date 而不必从一个大 _source 字段中提取这些字段。

4)boost

Elastic search入门到集群实战操作详解(原生API操作、springboot整合操作)-step1_第18张图片

 权重,新增数据时,可以指定该数据的权重,权重越高,得分越高,排名越靠前。

PUT my_index
{
    "mappings":{
        "_doc":{
            "properties":{
                "title":{
                    "type":"text",
                    "boost":2
                },
                "content":{
                    "type":"text"
                }
            }
        }
    }
}

title 字段上的匹配项的权重是字段上的匹配项的权重的两倍 content ,默认 boost 值为 1.0 。

提升仅适用于Term查询(不提升prefix,range和模糊查询)。

3.4.一次创建索引库和类型

第一步:
PUT /lagou
第二步:
PUT lagou/_mapping/goods
{
    "properties":{
        "title":{
            "type":"text",
            "analyzer":"ik_max_word"
        },
        "images":{
            "type":"keyword",
            "index":"false"
        },
        "price":{
            "type":"float"
        }
    }
}

刚才 的案例中我们是把创建索引库和类型分开来做,其实也可以在创建索引库的同时,直接制定索引库 中的类型,基本语法:


put /索引库名
{
    "settings":{
        "索引库属性名":"索引库属性值"
    },
    "mappings":{
        "类型名":{
            "properties":{
                "字段名":{
                    "映射属性名":"映射属性值"
                }
            }
        }
    }
}

示例:

PUT /lgt2

{
    "settings":{

    },
    "mappings":{
        "goods":{
            "properties":{
                "title":{
                    "type":"text",
                    "analyzer":"ik_max_word"
                }
            }
        }
    }
}

结果

{
  "acknowledged": true,
  "shards_acknowledged": true,
  "index": "lgt2"
}

4.使用kibana对文档操作

文档,即索引库中某个类型下的数据,会根据规则创建索引,将来用来搜索。可以类比做数据库中的每 一行数据。

4.1.新增文档

4.1.1.新增并随机生成id

通过POST请求,可以向一个已经存在的索引库中添加文档数据。

语法:

POST /索引库名/类型名

{

         "key":"value"

}

示例:

POST /lgt/goods/
{
"title": "小米手机",
"images": "http://image.xiaomi.com/12479122.jpg",
"price": 3899
}

响应:

{
  "_index": "lgt",
  "_type": "goods",
  "_id": "WF0FtHsBzd5g09u4tnbP",
  "_version": 1,
  "result": "created",
  "_shards": {
    "total": 2,
    "successful": 2,
    "failed": 0
  },
  "_seq_no": 0,
  "_primary_term": 1
}

Elastic search入门到集群实战操作详解(原生API操作、springboot整合操作)-step1_第19张图片

 可以看到结果显示为: created ,应该是创建成功了。

另外,需要注意的是,在响应结果中有个 _id 字段,这个就是这条文档数据的 唯一标示 ,以后的增删改 查都依赖这个id作为唯一标示,这里我们新增时没有指定id,所以是ES帮我们随机生成 的id。

7.2.查看文档

根据rest风格,新增是post,查询应该是get,不过查询一般都需要条件,这里我们把刚刚生成数据的id 带上。 通过kibana查看数据:

GET /lgt/goods/WF0FtHsBzd5g09u4tnbP

查看结果:

Elastic search入门到集群实战操作详解(原生API操作、springboot整合操作)-step1_第20张图片

  •  _source :源文档信息,所有的数据都在里面。
  • _id :这条文档的唯一标示
  • 自动生成的id,长度为20个字符,URL安全,base64编码,GUID(全局唯一标识符),分布式系统 并行生成时不可能会发生冲突
  • 在实际开发中不建议使用ES生成的ID,太长且为字符串类型,检索时效率低。建议:将数据表中 唯一的ID,作为ES的文档ID

4.3.新增文档并自定义id

如果我们想要自己新增的时候指定id,可以这么做:

POST /索引库名/类型/id值

{

        ...

}

示例:

POST /lgt/goods/2
{
"title": "小米手机",
"images": "http://image.xiaomi.com/12479122.jpg",
"price": 3899
}

得到结果数据:

{
  "_index": "lgt",
  "_type": "goods",
  "_id": "2",
  "_version": 1,
  "found": true,
  "_source": {
    "title": "小米手机",
    "images": "http://image.xiaomi.com/12479122.jpg",
    "price": 3899
  }
}

4.4.修改数据

PUT:修改文档

POST:新增文档

把刚才新增的请求方式改为PUT,就是修改了。不过修改必须指定id,

  • id对应文档存在,则修改
  • id对应文档不存在,则新增

操作和4.3类似!!

4.5.删除数据

删除使用DELETE请求,同样,需要根据id进行删除:

语法

DELETE /索引库名/类型名/id值

7.6.智能判断

刚刚我们在新增数据时,添加的字段都是提前在类型中定义过的,如果我们添加的字段并没有提前定义 过,能够成功吗?

事实上Elasticsearch非常智能,你不需要给索引库设置任何mapping映射,它也可以根据你输入的数据 来判断类型,动态添加数据映射。

示例

POST /lgt/goods/3
{
"title": "小米手机",
"images": "http://image.xiaomi.com/12479122.jpg",
"price": 3899,
"stock": 200,
"saleable": true,
"subTitle": "大米"
}

我们额外添加了stock库存,saleable是否上架,subtitle副标题、3个字段

结果:

{
  "_index": "lgt",
  "_type": "goods",
  "_id": "3",
  "_version": 1,
  "found": true,
  "_source": {
    "title": "小米手机",
    "images": "http://image.xiaomi.com/12479122.jpg",
    "price": 3899,
    "stock": 200,
    "saleable": true,
    "subTitle": "大米"
  }
}

成功了!我们看下索引库的映射关系!

GET /lgt

Elastic search入门到集群实战操作详解(原生API操作、springboot整合操作)-step1_第21张图片

 stock、saleable、subtitle都被成功映射了。

subtitle是String类型数据,ES无法智能判断,它就会存入两个字段。例如:

  • subtitle:text类型
  • subtitle.keyword:keyword类型

这种智能映射,底层原理是动态模板映射,如果我们想修改这种智能映射的规则,其实只要修改动态模 板即可!

4.7.动态映射模板

动态模板的语法:

Elastic search入门到集群实战操作详解(原生API操作、springboot整合操作)-step1_第22张图片

1)模板名称,随便起

2)匹配条件,凡是符合条件的未定义字段,都会按照这个规则来映射

3)映射规则,匹配成功后的映射规则

举例,我们可以把所有未映射的string类型数据自动映射为keyword类型:

PUT lgt3

{
    "mappings":{
        "goods":{
            "properties":{
                "title":{
                    "type":"text",
                    "analyzer":"ik_max_word"
                }
            },
            "dynamic_templates":[
                {
                    "strings":{
                        "match_mapping_type":"string",
                        "mapping":{
                            "type":"keyword",
                            "index":false,
                            "store":true
                        }
                    }
                }
            ]
        }
    }
}

在这个案例中,我们把做了两个映射配置:

  • title字段:统一映射为text类型,并制定分词器
  • 其它字段:只要是string类型,统一都处理为keyword类型。

这样,未知的string类型数据就不会被映射为text和keyword并存,而是统一以keyword来处理!

测试动态模块:

POST /lgt3/goods/1
{
"title":"超大米手机",
"images":"http://image.lagou.com/12479122.jpg",
"price":3299.00
}

我们只对title做了配置,现在来看看images和price会被映射为什么类型呢:

GET /lagou3/_mapping

Elastic search入门到集群实战操作详解(原生API操作、springboot整合操作)-step1_第23张图片

 可以看到images被映射成了keyword,而非之前的text和keyword并存,说明我们的动态模板生效了!

5.查询(重点)

5.1.基本查询

基本语法

GET /索引库名/_search

{
    "query":{
        "查询类型":{
            "查询条件":"查询条件值"
        }
    }
}

这里的query代表一个查询对象,里面可以有不同的查询属性

  • 查询类型:
            例如: match_all , match , term , range 等等
  • 查询条件:查询条件会根据类型的不同,写法也有差异,后面详细讲解

5.1.1 查询所有(match_all)

示例

GET /lgt/_search
{
  "query": {
    "match_all": {}
  }
}

  • query :代表查询对象
  • match_all :代表查询所有

结果

Elastic search入门到集群实战操作详解(原生API操作、springboot整合操作)-step1_第24张图片

 Elastic search入门到集群实战操作详解(原生API操作、springboot整合操作)-step1_第25张图片

  •  took:查询花费时间,单位是毫秒
  • time_out:是否超时
  • _shards:分片信息
  • hits:搜索结果总览对象
    • total:搜索到的总条数
    • max_score:所有结果中文档得分的最高分
    • hits:搜索结果的文档对象数组,每个元素是一条搜索到的文档信息
      • _index:索引库
      • _type:文档类型
      • _id:文档id
      • _score:文档得分
      • _source:文档的源数据

文档得分:使用ES时,对于查询出的文档无疑会有文档相似度之别。而理想的排序是和查询条件相关性 越高排序越靠前,而这个排序的依据就是_score

5.1.2 匹配查询(match)

分为and 、or 关系讲解

加入测试数据:

PUT /lgt/goods/4
{
"title": "小米电视4A",
"images": "http://image.xiaomi.com/12479122.jpg",
"price": 3899
}

or关系

match 类型查询,会把查询条件进行分词,然后进行查询,多个词条之间是or的关系

GET /lgt/_search
{
  "query": {
    "match": {
      "title": "小米手机"
    }
  }
}

在上面的案例中,不仅会查询到电视,而且与小米相关的都会查询到,多个词之间是 or 的关系。

Elastic search入门到集群实战操作详解(原生API操作、springboot整合操作)-step1_第26张图片

and关系

某些情况下,我们需要更精确查找:比如在电商平台精确搜索商品时,我们希望这个关系(查询条件切 分词之后的关系)变成 and (既要满足你,又要满足我),可以这样做:

GET /lgt/_search
{
  "query": {
    "match": {
      "title": {"query": "小米电视","operator": "and"}
    }
  }
}


本例中,只有同时包含 小米 和 电视 的词条才会被搜索到。

5.1.3 词条匹配(term)

 term 查询被用于精确值 匹配这些精确值可能是数字、时间、布尔或者那些未分词的字符 串,keyword类型的字符串

效果类似于:select * from tableName where colName='value'

GET lgt/_search
{
  "query": {
    "term": {
      "price": 3899
    }
  }
}

结果

Elastic search入门到集群实战操作详解(原生API操作、springboot整合操作)-step1_第27张图片

5.1.4 布尔组合(bool)

bool 把各种其它查询通过 must (与)、 must_not (非)、 should (或)的方式进行组合

## 查询结果:要查询title中包含手机,不包含电视,可以包含小米(前提是title中包含手机)

GET lgt/_search
{
  "query": {
    "bool": {
      "must": {"match": {"title" : "手机"}},
      "must_not": {"match": {"title": "电视"}},
      "should": {"match": {"title": "小米"}}
    }
  }
}

结果

Elastic search入门到集群实战操作详解(原生API操作、springboot整合操作)-step1_第28张图片

5.1.5 范围查询(range)

range 查询找出那些落在指定区间内的数字或者时间

GET lgt/_search
{
  "query": {
    "range": {
      "price": {
        "gte": 100,
        "lte": 1200
      }
    }
  }
}

range 查询允许以下字符:

操作符 说明
gt 大于

gte

大于等于

lt

小于
lte 小于等于

5.1.6 模糊查询(fuzzy)

fuzzy 查询是 term 查询的模糊等价,很少直接使用它。

我们新增一个商品:

PUT /lgt/goods/10
{
"title": "apple手机",
"images": "http://image.xiaomi.com/12479122.jpg",
"price": 5888
}

fuzzy 查询是 term 查询的模糊等价。它允许用户搜索词条与实际词条的拼写出现偏差,但是偏差的 编辑距离不得超过2

GET /lgt/_search
{
  "query": {
    "fuzzy": {
      "title": "appla"
    }
  }
}

上面的查询,也能查询到apple手机

Elastic search入门到集群实战操作详解(原生API操作、springboot整合操作)-step1_第29张图片

5.2.结果过滤

默认情况下,elasticsearch在搜索的结果中,会把文档中保存在 _source 的所有字段都返回。

如果我们只想获取其中的部分字段,我们可以添加 _source 的过滤

5.2.1.直接指定字段

示例

GET /lgt/_search
{
  "_source": ["title","price"], 
  "query": {
    "term": {
      "price": 5888
    }
  }
}

GET /lgt/_search
{
  "_source": {
    "includes": ["title","price"]
  }, 
  "query": {
    "term": {
      "price": 5888
    }
  }
}

返回结果

Elastic search入门到集群实战操作详解(原生API操作、springboot整合操作)-step1_第30张图片

 8.2.2.指定includes和excludes

我们也可以通过:

  • includes:来指定想要显示的字段
  • excludes:来指定不想要显示的字段

示例如上

5.3 过滤(filter)

Elasticsearch 使用的查询语言(DSL)拥有一套查询组件,这些组件可以以无限组合的方式进行搭配。 这套组件可以在以下两种情况下使用:过滤情况(filtering context)和查询情况(query context)。

如何选择查询与过滤:

通常的规则是,使用查询(query)语句来进行 全文 搜索或者其它任何需要影响 相关性得分 的搜索。 除此以外的情况都使用过滤(filters)

条件查询中进行过滤

所有的查询都会影响到文档的评分及排名。如果我们需要在查询结果中进行过滤,并且不希望过滤条件 影响评分,那么就不要把过滤条件作为查询条件来用。而是使用 filter 方式:

GET /lgt/_search
{
  "query": {
    "bool": {
      "must": {"match": {"title": "手机"}},
      "filter": {
        "range": {
          "price": {
            "gte": 10
          }
        }
      }
    }
  }
}

无查询条件,直接过滤

如果一次查询只有过滤,没有查询条件,不希望进行评分,我们可以使用 constant_score 取代只有 filter 语句的 bool 查询。在性能上是完全相同的,但对于提高查询简洁性和清晰度有很大帮助。

GET /lgt/_search
{
  "query": {
    "constant_score": {
      "filter": {
        "range": {
          "price": {
            "gte": 10
          }
        }
      }
    }
  }
}

5.4 排序

5.4.1 单字段排序

sort 可以让我们按照不同的字段进行排序,并且通过 order 指定排序的方式

GET lgt/_search
{
  "query": {
    "match": {
      "title": "手机"
    }
  },
  "sort": [
    {
      "price": {
        "order": "desc"
      }
    }
  ]
}

 5.4.2 多字段排序

假定我们想要结合使用 price和 _score(得分) 进行查询,并且匹配的结果首先按照价格排序,然后按 照相关性得分排序:

GET lgt/_search
{
  "query": {
    "bool": {
      "must": {"match" : {"title": "手机"}},
      "filter": {
        "range": {
          "price": {
            "gte": 10,
            "lte": 6000
          }
        }
      }
    }
  },
  "sort": [
    {
      "price": {
        "order": "desc"
      }
    },{
      "_score": {
        "order": "desc"
      }
    }
  ]
}

 5.5.分页

Elasticsearch中数据都存储在分片中,当执行搜索时每个分片独立搜索后,数据再经过整合返回。那 么,如果要实现分页查询该怎么办呢?

elasticsearch的分页与mysql数据库非常相似,都是指定两个值:

  • from:目标数据的偏移值(开始位置),默认from为0
  • size:每页大小

GET lgt/_search
{
  "query": {
    "match_all": {}
  },
  "sort": [
    {
      "price": {
        "order": "asc"
      }
    }
  ],
  "from": 1,
  "size": 2
}

结果

Elastic search入门到集群实战操作详解(原生API操作、springboot整合操作)-step1_第31张图片

 5.6.高亮

高亮原理:

  • 服务端搜索数据,得到搜索结果
  • 把搜索结果中,搜索关键字都加上约定好的标签
  • 前端页面提前写好标签的CSS样式,即可高亮

elasticsearch中实现高亮的语法比较简单:

GET lgt/_search
{
  "query": {
    "match": {
      "title": "手机"
    }
  },
  "highlight": {
    "pre_tags": "",
    "post_tags": "
",
    "fields": {
      "title": {}
    }
  }
}

在使用match查询的同时,加上一个highlight属性:

  • pre_tags:前置标签
  • post_tags:后置标签
  • fields:需要高亮的字段
    • title:这里声明title字段需要高亮

结果

Elastic search入门到集群实战操作详解(原生API操作、springboot整合操作)-step1_第32张图片

6. 聚合aggregations

聚合可以让我们极其方便的实现对数据的统计、分析。例如:

  • 什么品牌的手机最受欢迎?
  • 这些手机的平均价格、最高价格、最低价格?
  • 这些手机每月的销售情况如何?

实现这些统计功能的比数据库的sql要方便的多,而且查询速度非常快,可以实现近实时搜索效果。

6.1 基本概念

Elasticsearch中的聚合,包含多种类型,最常用的两种,一个叫 ,一个叫 度量

桶(bucket) 类似于 group by

桶的作用,是按照某种方式对数据进行分组,每一组数据在ES中称为一个 桶 ,例如我们根据国籍对人 划分,可以得到 中国桶 、 英国桶 , 日本桶 ……或者我们按照年龄段对人进行划分: 0~10,10~20,20~30,30~40等。

Elasticsearch中提供的划分桶的方式有很多:

  • Date Histogram Aggregation:根据日期阶梯分组,例如给定阶梯为周,会自动每周分为一组
  • Histogram Aggregation:根据数值阶梯分组,与日期类似,需要知道分组的间隔(interval)
  • Terms Aggregation:根据词条内容分组,词条内容完全匹配的为一组
  • Range Aggregation:数值和日期的范围分组,指定开始和结束,然后按段分组 ……

综上所述,我们发现bucket aggregations 只负责对数据进行分组,并不进行计算,因此往往bucket中 往往会嵌套另一种聚合:metrics aggregations即度量

度量(metrics) 相当于聚合的结果

分组完成以后,我们一般会对组中的数据进行聚合运算,例如求平均值、最大、最小、求和等,这些在 ES中称为 度量

比较常用的一些度量聚合方式:

  • Avg Aggregation:求平均值
  • Max Aggregation:求最大值
  • Min Aggregation:求最小值
  • Percentiles Aggregation:求百分比
  • Stats Aggregation:同时返回avg、max、min、sum、count等
  • Sum Aggregation:求和
  • Top hits Aggregation:求前几
  • Value Count Aggregation:求总数
  • ……

为了测试聚合,我们先批量导入一些数据 创建索引:

创建索引:

PUT /car

{
    "mappings":{
        "orders":{
            "properties":{
                "color":{
                    "type":"keyword"
                },
                "make":{
                    "type":"keyword"
                }
            }
        }
    }
}

注意:在ES中,需要进行聚合、排序、过滤的字段其处理方式比较特殊,因此不能被分词,必须使用 keyword 或 数值类型 。这里我们将color和make这两个文字类型的字段设置为keyword类型,这个类型 不会被分词,将来就可以参与聚合

导入数据,这里是采用批处理的API,大家直接复制到kibana运行即可:

POST /car/orders/_bulk
{ "index": {}}
{ "price" : 10000, "color" : "红", "make" : "本田", "sold" : "2020-10-28" }
{ "index": {}}
{ "price" : 20000, "color" : "红", "make" : "本田", "sold" : "2020-11-05" }
{ "index": {}}
{ "price" : 30000, "color" : "绿", "make" : "福特", "sold" : "2020-05-18" }
{ "index": {}}
{ "price" : 15000, "color" : "蓝", "make" : "丰田", "sold" : "2020-07-02" }
{ "index": {}}
{ "price" : 12000, "color" : "绿", "make" : "丰田", "sold" : "2020-08-19" }
{ "index": {}}
{ "price" : 20000, "color" : "红", "make" : "本田", "sold" : "2020-11-05" }
{ "index": {}}
{ "price" : 80000, "color" : "红", "make" : "宝马", "sold" : "2020-01-01" }
{ "index": {}}
{ "price" : 25000, "color" : "蓝", "make" : "福特", "sold" : "2020-02-12" }

6.2 聚合为桶

首先,我们按照 汽车的颜色 color来 划分 桶 ,按照颜色分桶,最好是使用TermAggregation类型,按 照颜色的名称来分桶。

GET /car/_search 
{
    "size": 0,
    "aggs": {
      "popular_color": {
        "terms": {
          "field": "make"
        },
        "aggs": {
          "avg_price": {
            "avg": {
              "field": "price"
            }
          },
          "max_price": {
            "max": {
              "field": "price"
            }
          }
        }
      }
    }
}
  • size: 查询条数,这里设置为0,因为我们不关心搜索到的数据,只关心聚合结果,提高效率
  • aggs:声明这是一个聚合查询,是aggregations的缩写
    • popular_colors:给这次聚合起一个名字,可任意指定。
      • terms:聚合的类型,这里选择terms,是根据词条内容(这里是颜色)划分
        • field:划分桶时依赖的字段

结果

Elastic search入门到集群实战操作详解(原生API操作、springboot整合操作)-step1_第33张图片

  • hits:查询结果为空,因为我们设置了size为0
  • aggregations:聚合的结果
  • popular_colors:我们定义的聚合名称
  • buckets:查找到的桶,每个不同的color字段值都会形成一个桶
    • key:这个桶对应的color字段的值
    • doc_count:这个桶中的文档数量

通过聚合的结果我们发现,目前红色的小车比较畅销!

6.3 桶内度量

前面的例子告诉我们每个桶里面的文档数量,这很有用。 但通常,我们的应用需要提供更复杂的文档度 量。 例如,每种颜色汽车的平均价格是多少?

因此,我们需要告诉Elasticsearch 使用哪个字段 , 使用何种度量方式 进行运算,这些信息要嵌套在 桶 内, 度量 的运算会基于 桶 内的文档进行

现在,我们为刚刚的聚合结果添加 求价格平均值的度量:

GET /car/_search 
{
    "size": 0,
    "aggs": {
      "popular_color": {
        "terms": {
          "field": "make"
        },
        "aggs": {
          "avg_price": {
            "avg": {
              "field": "price"
            }
          },
          "max_price": {
            "max": {
              "field": "price"
            }
          }
        }
      }
    }
}

  • aggs:我们在上一个aggs(popular_colors)中添加新的aggs。可见度量也是一个聚合
  • avg_price:聚合的名称
  • avg:度量的类型,这里是求平均值
  • field:度量运算的字段

可以看到每个桶中都有自己的 avg_price 字段,这是度量聚合的结果

到此ES的命令大部分已经讲解完毕,相信肯定也有了一定的了解。接下来我们看看ES集群以及Java API的操作以及整合Spring Boot Data ES

https://blog.csdn.net/qq_45441466/article/details/120116751

你可能感兴趣的:(分布式-微服务核心技术,elasticsearch,spring,boot)