1、ES是什么?

一个开源的分布式搜索引擎,可以用来实现搜索、日志统计、分析、系统监控等功能。ES的底层是基于Lucene实现的。

Lucene是一个Java语言的搜索引擎类库。

什么是elastic stack(ELK)?
  • elasticsearch。存储、计算、搜索数据
  • Kibana。数据可视化
  • Logstash、beats。数据抓取

2、倒排索引

ES数据库是基于倒排索引进行存储和查找的。

倒排索引是基于MySQL这样的正向索引而言的。

es 索引模板 object类型 es索引和类型_字段

正向索引流程:

es 索引模板 object类型 es索引和类型_es 索引模板 object类型_02

倒排索引中有两个非常重要的概念:

  • 文档(Document):用来搜索的数据,其中的每一条数据就是一个文档。例如一个网页、一个商品信息
  • 词条(Term):对文档数据或用户搜索数据,利用某种算法分词,得到的具备含义的词语就是词条。如:小米发布会开始。可以分词为:小米,发布会,发布,开始这几个词条。

其中词条具有唯一性,可以给其创建索引,如hash索引。加快检索速度。

在倒排索引中的搜索流程是:

  • 用户搜索“问界汽车”
  • 对小米汽车进行分词,分为“问界”,“汽车”
  • 去倒排索引中找,可以拿到文档id:2,3。
  • 拿着文档id去正向索引中查找具体文档。
  • 无论是词条查询,还是文档id查询,两个都建立了索引,查询速度都不低。

es 索引模板 object类型 es索引和类型_es 索引模板 object类型_03

3、ES数据库中的基本概念:

eS数据库中的概念

MySQL的概念

索引 (Index)

数据库 (Database)

类型 (Type)

表 (Table)

文档 (Document)

行 (Row)

字段 (Field)

列 (Column)

Mapping

架构 (Schema)

其中Type这个概念在es6的时候被废弃,es7中被完全删除,所以在上面表格中此时索引所对应的是表。

MySQL

Elasticsearch

说明

Table

Index

索引(index),就是文档的集合,类似数据库的表(table)

Row

Document

文档(Document),就是一条条的数据,类似数据库中的行(Row),文档都是JSON格式

Column

Field

字段(Field),就是JSON文档中的字段,类似数据库中的列(Column)

Schema

Mapping

Mapping(映射)是索引中文档的约束,例如字段类型约束。类似数据库的表结构(Schema)

SQL

DSL

DSL是elasticsearch提供的JSON风格的请求语句,用来操作elasticsearch,实现CRUD

4、索引库操作

索引库类似于数据库中的表,mapping类似于表结构。

所以想要在es中存储数据我们就需要先创建表。

4.1 Mapping的构建

再MySQL中构建一个表,其中一个字段有好多属性,如是否唯一,数据类型,数据大小,是否为外键等等。构建Mapping也是如此,其中一个字段也有一些需要设置的属性。

其中有一些常见属性需要设置:

  • type:字段数据类型,常见的简单类型有:
  • 字符串:text(可分词的文本)、keyword(精确值,例如:品牌、国家、ip地址)
  • 数值:long、integer、short、byte、double、float
  • 布尔:boolean
  • 日期:date
  • 对象:object
  • index:是否创建索引,默认为true。如果为true的话会为这个字段创建倒排索引。
  • analyzer:使用哪种分词器。
  • IK分词器包含两种模式:
  • ik_smart:最少切分
  • ik_max_word:最细切分
  • properties:该字段的子字段
{"age":21,

"weight":52.1,

"isMarried":false,

"info":"真相只有个!",

"email":"zy@itcast.cn",

"score":[99.1,99.5,98.9],

"name":{

"firstName":"柯",

"lastName":"南"}

}

对应的每个字段映射(mapping):

  • age:类型为 integer;参与搜索,因此需要index为true;无需分词器
  • weight:类型为float;参与搜索,因此需要index为true;无需分词器
  • isMarried:类型为boolean;参与搜索,因此需要index为true;无需分词器
  • info:类型为字符串,需要分词,因此是text;参与搜索,因此需要index为true;分词器可以用ik_smart
  • email:类型为字符串,但是不需要分词,因此是keyword;不参与搜索,因此需要index为false;无需分词器
  • score:虽然是数组,但是我们只看元素的类型,类型为float;参与搜索,因此需要index为true;无需分词器
  • name:类型为object,需要定义多个子属性
  • name.firstName;类型为字符串,但是不需要分词,因此是keyword;参与搜索,因此需要index为true;无需分词器
  • name.lastName;类型为字符串,但是不需要分词,因此是keyword;参与搜索,因此需要index为true;无需分词器
4.2 索引库的CRUD

CRUD简单描述:

  • 创建索引库:PUT /索引库名
  • 查询索引库:GET /索引库名
  • 删除索引库:DELETE /索引库名
  • 修改索引库(添加字段):PUT /索引库名/_mapping
  • 创建索引库
PUT /my_index
{
  "mappings": {
    "properties": {
      "name": {
        "type": "keyword"
      },
      "self-introduction": {
        "type": "text",
        "analyzer":"ik_smart"
      }
    }
  }
}
  • 查询索引库

GET /my_index

  • 删除索引库

DELETE /my_index

  • 修改索引库
//这里的修改是只能增加新的字段到mapping中,因为一旦修改Mapping结构,就需要重新构建倒排索引结构,那么工作量太大了。允许添加新的字段到mapping中,因为不会对倒排索引产生影响
PUT /my_index/_mapping
{
  "properties": {
    "age":{
      "type": "integer",
      "index":"false"
    }
  }
}

5、文档操作

文档操作有哪些?

  • 插入文档:POST /{索引库名}/_doc/文档id
  • 查询文档:GET /{索引库名}/_doc/文档id
  • 删除文档:DELETE /{索引库名}/_doc/文档id
  • 修改文档:
  • 全量修改:PUT /{索引库名}/_doc/文档id
  • 增量修改:POST /{索引库名}/_update/文档id { "doc": {字段}}
  • 插入文档
POST /my_index/_doc/1
{
    "name": "wubing",
    "self-introduction": "我是一个活泼开朗的人",
    "age": 21
}
  • 查询文档
GET /my_index/_doc/1

//批量查询:查询该索引库下的全部文档

GET /my_index/_search
  • 修改文档
//根据指定的id删除文档,新增一个相同id的文档
//注意:如果根据id删除时,id不存在,第二步的新增也会执行,也就从修改变成了新增操作了。
PUT /my_index/_doc/1
{
    "name": "wubing",
    "self-introduction": "我不是一个不活泼开朗的人",
    "age": 21
}
//增量修改是只修改指定id匹配的文档中的部分字段。
POST /my_index/_doc/1
{
    "doc": {
         "self-introduction": "我是一个活泼开朗的人",
    }
}
  • 删除文档

DELETE /my_index/_doc/1