1、ES是什么?
一个开源的分布式搜索引擎,可以用来实现搜索、日志统计、分析、系统监控等功能。ES的底层是基于Lucene实现的。
Lucene是一个Java语言的搜索引擎类库。
什么是elastic stack(ELK)?
-
elasticsearch。存储、计算、搜索数据
-
Kibana。数据可视化
-
Logstash、beats。数据抓取
2、倒排索引
ES数据库是基于倒排索引进行存储和查找的。
倒排索引是基于MySQL这样的正向索引而言的。
正向索引流程:
倒排索引中有两个非常重要的概念:
-
文档(
Document
):用来搜索的数据,其中的每一条数据就是一个文档。例如一个网页、一个商品信息 -
词条(
Term
):对文档数据或用户搜索数据,利用某种算法分词,得到的具备含义的词语就是词条。如:小米发布会开始。可以分词为:小米,发布会,发布,开始这几个词条。
其中词条具有唯一性,可以给其创建索引,如hash索引。加快检索速度。
在倒排索引中的搜索流程是:
-
用户搜索“问界汽车”
-
对小米汽车进行分词,分为“问界”,“汽车”
-
去倒排索引中找,可以拿到文档id:2,3。
-
拿着文档id去正向索引中查找具体文档。
-
无论是词条查询,还是文档id查询,两个都建立了索引,查询速度都不低。
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