Elasticsearch
Elasticsearch是由elastic公司开发的一套搜索引擎技术,它是elastic技术栈中的一部分。完整的技术栈包括:
-
Elasticsearch:用于数据存储、计算和搜索
-
Logstash/Beats:用于数据收集
-
Kibana:用于数据可视化
整套技术栈被称为ELK,经常用来做日志收集、系统监控和状态分析等等
整套技术栈的核心就是用来存储、搜索、计算的Elasticsearch,因此我们接下来学习的核心也是Elasticsearch。
倒排索引
文档(Document
):用来搜索的数据,其中的每一条数据就是一个文档
词条(Term
):对文档数据或用户搜索数据,利用某种算法分词,得到的具备含义的词语就是词条。
创建倒排索引是对正向索引的一种特殊处理和应用,流程如下:
-
将每一个文档的数据利用分词算法根据语义拆分,得到一个个词条
-
创建表,每行数据包括词条、词条所在文档id、位置等信息
-
因为词条唯一性,可以给词条创建正向索引
此时形成的这张以词条为索引的表,就是倒排索引表
正向索引:
-
优点:
-
可以给多个字段创建索引
-
根据索引字段搜索、排序速度非常快
-
-
缺点:
-
根据非索引字段,或者索引字段中的部分词条查找时,只能全表扫描。
-
倒排索引:
-
优点:
-
根据词条搜索、模糊搜索时,速度非常快
-
-
缺点:
-
只能给词条创建索引,而不是字段
-
无法根据字段做排序
-
基础概念
.文档和字段
elasticsearch是面向文档(Document)存储的,可以是数据库中的一条商品数据,一个订单信息。文档数据会被序列化为json
格式后存储在elasticsearch
中
原本数据库中的一行数据就是ES中的一个JSON文档;而数据库中每行数据都包含很多列,这些列就转换为JSON文档中的字段(Field)。
索引和映射
我们要将类型相同的文档集中在一起管理,称为索引(Index)
数据库的表会有约束信息,用来定义表的结构、字段的名称、类型等信息。因此,索引库中就有映射(mapping),是索引中文档的字段约束信息,类似表的结构约束。
IK分词器
Elasticsearch的关键就是倒排索引,而倒排索引依赖于对文档内容的分词,而分词则需要高效、精准的分词算法,IK分词器就是这样一个中文分词算法。
IK分词器包含两种模式:
-
ik_smart
:智能语义切分 -
ik_max_word
:最细粒度切分
Index就类似数据库表,Mapping映射就类似表的结构。我们要向es中存储数据,必须先创建Index和Mapping
Mapping映射属性
Mapping是对索引库中文档的约束,常见的Mapping属性包括:
-
type
:字段数据类型,常见的简单类型有:-
字符串:
text
(可分词的文本)、keyword
(精确值,例如:品牌、国家、ip地址) -
数值:
long
、integer
、short
、byte
、double
、float
、 -
布尔:
boolean
-
日期:
date
-
对象:
object
-
-
index
:是否创建索引,默认为true
-
analyzer
:使用哪种分词器 -
properties
:该字段的子字段
由于Elasticsearch采用的是Restful风格的API,因此其请求方式和路径相对都比较规范,而且请求参数也都采用JSON风格。
我们直接基于Kibana的DevTools来编写请求做测试,由于有语法提示,会非常方便。
创建索引库和映射
基本语法:
-
请求方式:
PUT
-
请求路径:
/索引库名
,可以自定义 -
请求参数:
mapping
映射
查询索引库
基本语法:
-
请求方式:GET
-
请求路径:/索引库名
-
请求参数:无
修改索引库
倒排索引结构虽然不复杂,但是一旦数据结构改变(比如改变了分词器),就需要重新创建倒排索引,这简直是灾难。因此索引库一旦创建,无法修改mapping。
虽然无法修改mapping中已有的字段,但是却允许添加新的字段到mapping中,因为不会对倒排索引产生影响。因此修改索引库能做的就是向索引库中添加新字段,或者更新索引库的基础属性。
删除索引库
语法:
-
请求方式:DELETE
-
请求路径:/索引库名
-
请求参数:无
索引库操作有哪些?
-
创建索引库:PUT /索引库名
-
查询索引库:GET /索引库名
-
删除索引库:DELETE /索引库名
-
修改索引库,添加字段:PUT /索引库名/_mapping
可以看到,对索引库的操作基本遵循的Restful的风格,因此API接口非常统一,方便记忆。
文档操作有哪些?
-
创建文档:
POST /{索引库名}/_doc/文档id { json文档 }
-
查询文档:
GET /{索引库名}/_doc/文档id
-
删除文档:
DELETE /{索引库名}/_doc/文档id
-
修改文档:
-
全量修改:
PUT /{索引库名}/_doc/文档id { json文档 }
-
局部修改:
POST /{索引库名}/_update/文档id { "doc": {字段}}
-
JavaRestClient操作elasticsearch的流程基本类似。核心是client.indices()
方法来获取索引库的操作对象。
索引库操作的基本步骤:
-
初始化
RestHighLevelClient
-
创建XxxIndexRequest。XXX是
Create
、Get
、Delete
-
准备请求参数(
Create
时需要,其它是无参,可以省略) -
发送请求。调用
RestHighLevelClient#indices().xxx()
方法,xxx是create
、exists
、delete
文档操作的基本步骤:
-
初始化
RestHighLevelClient
-
创建XxxRequest。
-
XXX是
Index
、Get
、Update
、Delete
、Bulk
-
-
准备参数(
Index
、Update
、Bulk
时需要) -
发送请求。
-
调用
RestHighLevelClient#.xxx()
方法,xxx是index
、get
、update
、delete
、bulk
-
-
解析结果(
Get
时需要)