基本概念,索引、文档、RESTAPI
- 文档
- ElasticSearch是面向文档的,文档是可搜索数据的最小单位
比如:日志中的日志项,一张唱片的详细信息
相当于数据库中的一条记录 - 文档会被序列化成json格式,保存在es中
json对象由字段组成
每个字段都有对应的字段类型(字符串/数值/布尔/日期/二进制/范围类型) - 每个文档都有一个Unique ID
你可以自己指定unique ID
或者通过es自动生成 - 文档的元数据
- ElasticSearch是面向文档的,文档是可搜索数据的最小单位
- 索引
- 索引就是一类文档的集合
每个索引都有自己的Mapping定义,用于定义包含的文档的字段名和字段类型
索引中的数据分散在shard上 - 索引的mapping与settings
mapping定义文档字段的类型
setting定义不同的数据分布 - 类比关系型数据库
- 索引就是一类文档的集合
节点、集群、分片、副本
- 分布式系统的可用性和扩展性
- 高可用性
服务可用性:允许有节点停止服务,但是整体仍然对外提供服务
数据可用性:部分节点丢失,不会丢失数据 - 可扩展性
请求量提升/数据不断增长,可以水平扩展到其他机器 - es的分布式架构的好处
存储的水平扩容
提高系统的可用性,部分节点停止服务,整个集群的服务不受影响 - es的分布式架构
不同的集群通过不同的名字来区分,默认名字“elasticsearch”
通过配置文件修改,或者在命令行中 -E cluster.name=geektime进行设定
一个集群可以有一个或者多个节点
- 高可用性
- 节点
- 节点是一个es实例
本质上是一个java进程
一台机器上可以运行多个es进程,但是生产环境建议一台机器只运行一个es实例 - 每个节点都有名字,可以通过配置文件配置,或者启动时候 -E node.name=node1配置
- 每一个节点在启动之后,会分配一个UID,保存在data目录下
- Master-eligible node和master node
- 每个节点启动后,默认是一个master-eligible节点
可以设置node.master:false禁止 - master-eligible节点可以参与选主流程,成为master节点
- 当第一个节点启动时候,它会将自己选举为master节点
- 每个节点上都保存了集群的状态,只有master节点才能修改集群的状态信息
- 集群状态,维护了一个集群中必要的信息
所有节点信息
所有的索引和其相关的Mapping与Setting信息
分片的路由信息 - 任意节点都能修改信息会导致数据的不一致性
- 集群状态,维护了一个集群中必要的信息
- 每个节点启动后,默认是一个master-eligible节点
- Data Node和Coordinating Node
- Data Node
可以保存数据的节点。负责保存分片数据,在数据扩展上起到了至关重要的作用。 - Coordinating Node
负责接收Client的请求,将请求分发到合适的节点,最终把结果汇集到一起
每个节点默认都起到了Coordinating Node的职责
- Data Node
- Hot&Warm Node
不同硬件配置的Data Node,用来实现Hot&Warm架构,降低集群部署的成本 - Machine Learning Node
负责跑机器学习的Job,用来做异常检测 - 配置节点类型
- 节点是一个es实例
- 分片
- 主分片
解决数据水平扩展的问题,通过主分片,可以将数据分布在集群所有的节点上。
主分片数在索引创建时指定,后续不允许修改,除非Reindex - 副本分片
解决数据高可用的问题
副本分片数可以动态调整
增加副本分片数,还可以提高服务的可用性 - 查看集群的健康状况
get _cluster/health
Green:主分片与副本分片都正常分配
Yellow:主分片正常分配,有副本分片未能正常分配
Red:有主分片未能分配
- 主分片
文档基本的CRUD和批量操作
- Create一个文档
- 支持自定生成文档Id和指定文档Id两种方式
- 通过调用“POST users/_doc”
系统会自动生成document Id - 使用http PUT users/_create/1创建时,URI中显示指定_create,此时如果该id的文档已经存在,操作失败
- Get一个文档
GET users/_doc/1
找到文档,返回HTTP 200
找不到文档,返回HTTP 404 - Index文档
Index和Create不一样的地方,如果文档不存在那么新建文档,否则删除现有文档,新建文档,版本信息+1
PUT users/_doc/1 - Update文档
Update方法不会删除原来的文档,而是实现数据的更新
POST users/_update/1 - Bulk API
- 支持在一次API调用中,对不同的索引进行不同的操作
- 支持四种操作类型:
Index
Create
Update
Delete - 可以在URI中指定Index,也可以在请求的Payload中进行
- 操作中单条操作失败,并不会影响其他操作
- 返回结果包括每一条操作执行的结果
- mget操作
GET /_mget
- 常见错误返回
倒排索引介绍
- 搜索引擎
- 正排与倒排索引
正排索引:文档id到文档内容和单词的关联
倒排索引:单词到文档id的关系 - 倒排索引包含两部分
- 单词词典
记录所有文档的单词,记录单词与倒排列表的关联关系
单词词典一般比较大,可以通过B+树或哈希拉链法实现,满足高性能的插入与查询 - 倒排列表
记录了单词对应的文档集合,由倒排索引项组成- 倒排索引项
文档ID
词频TF:该单词在文档中出现的次数,用于相关性评分
位置:单词在文档中分词的位置,用于语句搜索
偏移:记录单词的开始结束位置,实现高亮显示
- 倒排索引项
- 单词词典
- ES的倒排索引
ES的JSON文档中的每个字段,都有自己的倒排索引
可以指定对某些字段不做索引:
优点:节省存储空间
缺点:字段无法被搜索
- 正排与倒排索引
分词器
- Analysis
文本分析是把全文本转换成一系列单词的过程,也叫分词 - Analyzer
分词器
Analysis通过分词器来实现,可以使用es内置的分词器也可以定制化分词器 - 除了在数据写入时转换词条,匹配Query语句时也需要使用相同的分词器对查询语句进行分析
- Analyzer的组成
由三部分组成
Character Filters:针对原始文本处理,例如去除html标签
Tokenizer:按照规则切分为单词,例如按照空格切分
Token Filter:将切分的单词进行加工,例如小写、删除停顿词、增加同义词 - 测试分词效果
GET _analyze接口
- 各种分词器
- Standard
默认分词器
按词切分
小写处理 - Simple
按照非字母切分,非字母的都被去除
小写处理 - WhiteSpace
按照空格切分 - Stop
相比于Simple,多了stop filter会把停顿词例如in、the、a去除 - KeyWord
不做分词处理 - Pattern
通过正则表达式进行分词
默认是\W+,非字符的符号进行分隔 - Language
可以指定不同的语言进行分词
例如:english - ICU—中文分词器
需要安装plugin
Elasticsearch-plugin install analysis-icu - 更多的中文分词器
- IK
支持自定义词库,支持热更新分词字典
https://github.com/medcl/elasticsearch-analysis-ik - THULAC
https://github.com/microbun/elasticsearch-thulac-plugin
- IK
- Standard
SearchAPI概览
- Search API
- URI Search
Get请求,在URL中使用查询参数
使用“q”指定查询字符串
“http://elasticsearch:9200/kibana_sample_data_ecommerce/_search?q=customer_first_name:Eddie” - Request Body Search
使用es提供的,基于json格式的更加完备的DSL
- URI Search
- 指定查询的索引
/_search 集群上的所有索引
/index1/_search index1索引
/index1,index2/_search index1和index2
/index*/_search 以index开头的索引 - 衡量相关性
Precision(查准率):尽可能返回较少的无关文档,返回的相关文档数/全部返回的结果数
Recall(查全率):尽量返回较多的相关文档,返回的相关文档数/所有应该返回的结果数
Ranking:按照相关度进行排序
使用es的查询和相关的参数可以改善搜索的Precision和Recall - URI Search详解
- 通过URI query实现搜索
q指定查询语句
df指定字段,不指定时,对所有字段进行查询
sort排序/from、size用于分页
profile可以查看查询是如何被执行的 - 查询语句
- 指定字段 vs 泛查询
q=title:2012 q=2012 - Term vs Phrase
title:(Beautiful Mind)等效于Beautiful OR Mind
title:"Beautiful Mind"等效于Beautiful AND Mind - 布尔操作
AND/OR/NOT - 分组
+表示must
-表示must_not - 范围查询
[]闭区间,{}开区间
year:{2019 TO 2018}
year:[* TO 2018] - 算数符号
year:>2010
year:(>2010 && <=2018)
year:(+>2010 +<=2018) - 通配符查询
?代表一个字符
*代表0或多个字符 - 正则表达
title:[bt]oy - 模糊匹配与近似查询
title:beautifl~1
title:“load rings”~2
- 指定字段 vs 泛查询
- 通过URI query实现搜索
- RequestBody与Query DSL
将查询语句通过HTTP Request Body发送给es
Query DSL
- 分页
“from”:10,
“size”:20 - 排序
“sort”:[{“order_date”:“desc”}] - _source filter
“_source”: [“order_date”, “keyword”] - 脚本字段
- match查询
Last和Christmas是or
- match_phrase查询
slop允许中间出现的其他单词数
- 分页
- Query String
Dynamic Mapping和常见字段类型
- Mapping类似数据库中的schema的定义
定义字段名称
定义字段的数据类型
字段,倒排索引的相关配置 - 字段的数据类型
- 简单类型
Text/Keyword
Date
Integer/Floating
Boolean
IPV4/IPV6 - 复杂类型
对象类型/嵌套类型 - 特殊类型
geo_point&geo_shape/percolator
- 简单类型
- 什么是Dynamic Mapping
- 在写入文档的时候,如果索引不存在,会自动创建索引
- Dynamic Mapping的机制,使得我们无需手动定义Mappings,es会根据文档信息,推算出字段的类型
- 但是有时候会推算的不对,例如地理位置信息
- 当类型设置不对时,会导致一些功能无法正常使用
- 能否更改Mapping的字段类型
- 新增字段
- Dynamic设置为true时,一旦有新增字段的文档写入,Mapping也同时被更新
- Dynamic设置为false,Mapping不会被更新,新增字段的数据无法被索引,但是信息会出现在_source中
- Dynamic设置为strict,文档写入失败
- 对于已有字段,一旦有数据写入,不再支持修改字段定义
- 因为lucene的倒排索引,一旦生成后就不允许修改
- 如果希望修改字段类型,必须Reindex API,重建索引
- 新增字段
- 控制Dynamic Mappings
- 设置为true,文档可以写入,新增字段可以被搜索,Mapping被更新
- 设置为false,文档可以写入,新增字段不可以被搜索,Mapping不被更新
- 设置为strict,文档不可以写入,新增字段无法搜索,Mapping不被更新
显示Mapping设置
- 自定义Mapping的建议
- 可以参考API手册,纯手写
- 可以依照以下步骤:
- 创建一个临时的Index,写入一些样本数据
- 通过访问Mapping API获取该临时Index的Mapping定义
- 查看字段类型是否符合需求,进行修改后使用该配置创建自己的索引
- 删除临时索引
- 常见属性
- 字段的index属性
控制字段是否能被搜索 - 字段的index_options属性
四种不同级别的Index Options属性,可以控制倒排索引记录的内容
Text类型默认为positions,其他默认为docs
记录内容越多,占用空间越大- docs—记录doc id
- freqs—记录doc id和term frequencies
- positions—记录doc id/ term frequencies/ term position
- offsets—doc id/ term frequencies / term position / character offsets
- 字段的index属性
- null_value
需要对NULL值实现搜索
只有Keyword类型支持设定null_value - 数组类型
es中不提供专门的数组类型,但是任何字段,都可以包含多个相同类型的数据
多字段以及Mapping自定义Analyzer
- 精确值以及全文本
- 精确值
包括数字/日期/具体一个字符串(例如"Apple Store")
es中的keyword,不需要进行分词 - 全文本,非结构化数据
es中的text,需要进行分词
- 精确值
- 自定义分词器
组合三个部分- Character Filters
在Tokenizer之前对文本进行处理,例如增加删除以及替换字符,可以配置多个 Character Filters
自带的 Character Filters:
HTML strip —— 去除html标签
Mapping ——字符串替换
Pattern replace ——正则匹配替换 - Tokenizer
将原始的文本按照一定规则,切分为词
es内置的tokenizer:
whitespace/standard/uax_url_email/pattern/keyword/path hierarchy - Token Filters
将Tokenizer输出的单词,进行增加、修改、删除
自带的token filters:
lowercase/ stop / synonym
- Character Filters
- 创建index时,自定义analyzer