ElasticSearch索引数据库的使用

ElasticSearch索引数据库的使用

Scroll Down

一、简述

1、Elasticsearch和MongoDB/Redis/Memcache一样,是非关系型数据库。是一个接近实时的搜索平台,从索引这个文档到这个文档能够被搜索到只有一个轻微的延迟,企业应用定位:采用Restful API标准的可扩展和高可用的实时数据分析的全文搜索工具。

2、可拓展:支持一主多从且扩容简易,只要cluster.name一致且在同一个网络中就能自动加入当前集群;本身就是开源软件,也支持很多开源的第三方插件。

3、高可用:在一个集群的多个节点中进行分布式存储,索引支持shards和复制,即使部分节点down掉,也能自动进行数据恢复和主从切换。

3、采用RestfulAPI标准:通过http接口使用JSON格式进行操作数据。

4、数据存储的最小单位是文档,本质上是一个JSON 文本:

image

二、ElasticSearch安装

了解ELK

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

其中Elasticsearch是一个基于Lucene、分布式、通过Restful方式进行交互的近实时搜索平台框架。

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

Kibana可以将elasticsearch的数据通过友好 的页面展示出来,提供实时分析的功能。

市面上很多开发只要提到ELK能够一致说出它是一个日志分析架构技术栈总称,但实际上ELK不仅仅适用 于日志分析,它还可以支持其它任何数据分析和收集的场景,日志分析和收集只是更具有代表性。并非 唯一性。

image.png

Docker下安装es

下载镜像

$ docker pull elasticsearch

运行es

$ docker run --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -d elasticsearch:7.7.0
$ curl http://localhost:9200

接下来可以打开http://localhost:9200或者上面的指令来检查是否成功运行
image.png

Windows安装Kibana

Kibana 版本要和 Es 版本是一致的

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

下载解压后得到如图文件夹

image.png

bin目录包含了启动脚本,我们只需要点击kibana.bat即可启动kibana

config包含kibana的配置文件,当我们的es服务器不是在本地时,可以在这里进行修改。

image.png

如果想修改kibana为中文界面可以修改为
image.png

Docker安装Kibana

$ docker pull kibana:7.7.0  //获取镜像

$ docker logs docker run --name kibana --link=elasticsearch:7.7.0  -p 5601:5601 -d kibana:7.7.0 //运行Kibana

运行成功后打开127.0.0.1:5601即可

image.png

IK分词器插件

分词:即把一段中文或者别的划分成一个个的关键字,我们在搜索时会把自己的信息进行分词,会把数据库或者索引库中的数据进行分词,然后进行一个个匹配操作,默认的中文分词器是将每个字看成一个词。

IK提供了两种分词算法:

  • ik_smart:最小切分
  • ik_max_word:最细粒度划分

windows安装

1、https://github.com/medcl/elasticsearch-analysis-ik
2、下载完毕之后,放入到我们的elasticsearch 插件即可!

Docker安装

$ docker exec -it es /bin/bash
$ elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v7.7.0/elasticsearch-analysis-ik-7.7.0.zip

三、ES核心概念

image.png

elasticsearch(集群)中可以包含多个索引(数据库),每个索引中可以包含多个类型(表),每个类型下又包含多个文档(行),每个文档中又包含多个字段(列)。

物理设计

elasticsearch 在后台把每个索引划分成多个分片,每分分片可以在集群中的不同服务器间迁移

一个人就是一个集群!默认的集群名称就是 elaticsearh

image.png

逻辑设计

一个索引类型中,包含多个文档,比如说文档1,文档2。 当我们索引一篇文档时,可以通过这样的一各 顺序找到它: 索引 ▷ 类型 ▷ 文档ID ,通过这个组合我们就能索引到某个具体的文档。 注意:ID不必是整数,实际上它是个字符串。

文档

user
1	zhangsan	18
2	kuangshen	3

之前说elasticsearch是面向文档的,那么就意味着索引和搜索数据的最小单位是文档,elasticsearch 中,文档有几个 重要属性 :

  • 自我包含,一篇文档同时包含字段和对应的值,也就是同时包含 key:value!
  • 可以是层次型的,一个文档中包含自文档,复杂的逻辑实体就是这么来的! {就是一个json对象! fastjson进行自动转换!}
  • 灵活的结构,文档不依赖预先定义的模式,我们知道关系型数据库中,要提前定义字段才能使用, 在elasticsearch中,对于字段是非常灵活的,有时候,我们可以忽略该字段,或者动态的添加一个新的字段

尽管我们可以随意的新增或者忽略某个字段,但是,每个字段的类型非常重要,比如一个年龄字段类 型,可以是字符 串也可以是整形。因为elasticsearch会保存字段和类型之间的映射及其他的设置。这种 映射具体到每个映射的每种类型,这也是为什么在elasticsearch中,类型有时候也称为映射类型。

类型

image.pngimage.png

类型是文档的逻辑容器,就像关系型数据库一样,表格是行的容器。 类型中对于字段的定义称为映射, 比如 name 映射为字符串类型。

我们说文档是无模式的,它们不需要拥有映射中所定义的所有字段, 比如新增一个字段,那么elasticsearch是怎么做的呢?

elasticsearch会自动的将新字段加入映射,但是这个字段的不确定它是什么类型,elasticsearch就开始猜,如果这个值是18,那么elasticsearch会认为它是整形。

但是elasticsearch也可能猜不对,所以最安全的方式就是提前定义好所需要的映射,这点跟关 系型数据库殊途同归了,先定义好字段,然后再使用。

索引

索引相当于数据库

索引是映射类型的容器,elasticsearch是一个非常大的文档集合。索引储存了映射类型的字段和其他设置。然后它们被存储到各个分片上。

物理设计:节点和分片如何工作

一个集群至少有一个节点,而一个节点就是elasitcsearch进程,节点可以有多个默认的索引。如果你创建索引,那么所以呢将会有5个分片(Primary Shard,又称为主分片)构成,每个主分片会有一个副本(replica shard,又称复制分片)

image.png

上图是一个有3个节点的集群,可以看到主分片和对应的复制分片都不会在同一个节点内,这样有利于某个节点挂掉 了,数据也不至于丢失。

实际上,一个分片是一个Lucene索引,一个包含倒排索引的文件 目录,倒排索引的结构使 得elasticsearch在不扫描全部文档的情况下,就能告诉你哪些文档包含特定的关键字。

倒排索引

elasticsearch使用的是一种称为倒排索引的结构,采用Lucene倒排索作为底层。这种结构适用于快速的全文搜索, 一个索引由文档中所有不重复的列表构成,对于每一个词,都有一个包含它的文档列表。 例如,现在有两个文档, 每个文档包含如下内容:

Study every day, good good up to forever # 文档1包含的内容

To forever, study every day, good good up # 文档2包含的内容

为了创建倒排索引,我们首先要将每个文档拆分成独立的词(或称为词条或者tokens),然后创建一个包含所有不重复的词条的排序列表,然后列出每个词条出现在哪个文档 :

image.png

现在,我们试图搜索 to forever,只需要查看包含每个词条的文档 score

image.png

两个文档都匹配,但是第一个文档比第二个匹配程度更高。如果没有别的条件,现在,这两个包含关键字的文档都将返回。

再来看一个示例,比如我们通过博客标签来搜索博客文章。那么倒排索引列表就是这样的一个结构 :

image.png

如果要搜索含有 python 标签的文章,那相对于查找所有原始数据而言,查找倒排索引后的数据将会快的多。只需要查看标签这一栏,然后获取相关的文章ID即可。完全过滤掉无关的所有数据,提高效率!

Rest风格说明

一种软件架构风格,而不是标准,只是提供了一组设计原则和约束条件。它主要用于客户端和服务器交 互类的软件。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。

image.png

关于索引的基本操作

创建索引

PUT /索引名/~类型名~/文档id
{
请求体
}

image.png

image.png

指定类型

  • 字符串类型
    text、keyword

  • 数值类型
    long, integer, short, byte, double, float, half_float, scaled_float

  • 日期类型
    date

  • 布尔类型
    boolean

  • 二进制类型
    binary

  • 等等

如果需求指定字段类型,可用以下方法
image.png

文档的基本操作

1、添加数据 PUT

PUT /ajar/user/1
{
  "name":"嘉",
  "age":23,
  "desc":"爱好打王者",
  "tags":["直男","海底捞爱好者"]
}

image.png

2、获取数据 GET

GET /ajar/user/1

image.png

3、更新数据 POST _update

POST /ajar/user/1/_update
{
  "doc":{
      "name":"嘉"
  }
}

不推荐使用PUT,因为没填的字段会被覆盖掉
image.png

可以使用
image.png

查询

GET /ajar/user/_search?q=desc:爱好打王者

image.png

查询的参数使用Json结构

GET /ajar/user/_search
{
  "query": {
    "match": {
      "name": "嘉"
    }
  },
    "_source":["name","desc"],
    "sort": [
      {
        "age": {
          "order": "desc"
        }
      }
    ],
    "from": 0,
    "size": 1
}

hit:索引和文档的信息,查询结果的总数

max_score:判断更加准确的结果

_source:结果过滤

sort:排序

from:从第几条数据开始

size:返回数据条数

image.png

must:相当于and

should:相当于or

must_not:相当于not

GET /ajar/user/_search
{
  "query": {
    "bool": {
      "should": [
        {"match": {
          "name": "嘉"
        }}
      ]
    }
  }
}

filter:过滤器

GET /ajar/user/_search
{
  "query": {
    "bool": {
          "filter":{
            "range":{
                "age":{
                  "lt":30
                }
            }
    	}
    }
  }
}
  • gt 大于
  • get 大于等于
  • li 小于
  • lte 小于等于

使用空格匹配多个条件,通过分值来进行结果的判断
image.png

term查询:直接通过倒排索引指定的词条进行精确查找

关于分词

  • term :直接查询精确的
  • match :会使用分词器解析!(先分析文档,然后在通过分析的文档进行查询!)