倒排索引
- 单词词典
文档所有单词
B+🌲 - 倒排列表
- 文档ID
- 词频TF
- 位置 - 语句搜索
- 偏移 - 高亮
Analyzer 分词
Character Filter - Tokenizer - Token Filter
对原始文本处理 按照规则切分 将切分的单词进行加工
_analyzer API
```curl
GET _analyze
{
"analyzer" : "name"
"text" : "str"
}
```
search API
filter Context -> 不算分
query Context -> 算分
词项搜索(Term) VS 全文本查询
词项搜索(Term)
不分词 //term
```curl
POST /index/_search
{
"query":{
"term":{
"desc":{
"value":"iphone"
}
}
}
}
```
constonst_score -> filter -> 不算分
全文本
分词 A,B //match , match phrase,query string
```curl
"query":{
"match":{
"title":{
"query": "A B"
"operate": "AND"
}
}
}
```
URI 查询
```curl
GET /movies/_search?q=2012&df=title&sort=year:desc&from=0&size=10&timeout=1s{
"profile" : true
}
q - 查询语句
df - 默认字段 不指定则全部字段
q=title:2012
sort 排序
from,size - 分页
profile - v
```
指定字段
q=title:2012 - 指定查询
q=2012 - 泛查询
Term vs Phrase
Term
q=title:Beautiful Mind
Phrase - 顺序
q=title:"Beautiful Mind" - and
分组和引导
q = title:(Beautifun OR Mind) - or
AND OR NOT
q = title:(Beautifun OR Mind) - or
> < >= <=
GET /movices/_search?q=year:>=1980
Disjunction Max Query
- 单字符串多字段查询,字段竞争
- 一个字段评分最高则为最终得分
- tie_breaker 设置将不是最优评分的字段*这个参数之后参与算分
```curl
"query":{
"dis_max":{
"queries":[
{"match":{"title": "A B"}}
{"match":{"body": "A B"}}
],
"tie_breaker" : 0.1
}
}
```
Mutil Match
多字符串,多字段查询
Best Field
- 在fileds中选取得分最高多
- 可以通过tie_breaker细调
```curl
"query":{
"mutil_match":{
"type": "best_fields",
"query": "A B",
"fields":["title","body"],
"tie_breaker": 0.2,
"minimun_should_match": "20%"
}
}
```
Most Field
- fileds字段得分相加
```curl
"query":{
"mutil_match":{
"type": "most_match",
"query": "A B",
"fields":["title","body"],
}
}
```
Cross Field
搜索字符出现在多个字段得分最多
```curl
"query":{
"mutil_match":{
"type": "cross_match",
"query": "A B",
"fields":["title","body"],
}
}
```
bool
must
should
must_not
filter
boosting match
影响算分结果
positive
negative
```curl
"query":{
"bossting":{
"positive":{
"match":{
"field": "field_name"
}
}
}
}
```
通配
q=title:b*
相似查询
q=title:beaufifl~1
q=title:“Load Rings”~2
Reaquest Body
功能齐全
query_string 和 simple_query_string
```curl
GET /index/_doc/_search
{
"query" :{
"query_string":{
"default_field" : "name",
"query" : "A AND B"
}
}
}
```
```curl
GET /index/_doc/_search
{
"query" :{
"simple_query_string":{
"query" : "A - B"
“fields" : ["name"]
}
}
}
```
simple - 默认term为OR
支持
+ + AND
+ | OR
+ - NOT
聚合分析
Bucket Agg - Group
```curl
GET index/_search
{
"aggs":{
"name":{
"terms":{
"field":"field_name"
}
}
}
}
```
Metric Agg - Count
```curl
GET index/_search
{
"aggs":{
"name":{
"terms":{
"field":"field_name"
}
},
"aggs":{
"avg_age":{
"avg":{
"field":"age"
}
}
},
"money":{
"terms":{
"field": "money"
}
}
}
}
```
Pipeline Agg
Matri Agg
Mapping
索引的字段定义
设置
-
Index
- docs - doc id
- freqs - doc id + frequenceies
- positions - doc id + fre + position
- offsets - id + fre + pos + offset
copy_to
null_value
Analyzer
Dynamic Mapping
- true - 自动创建mapping
- false - 无法被搜索
- stitc - 无法索引
Dynamic Template
```curl
PUT my_test_index
{
"mappings":{
"dynamic_templates":[
{
"full_name":{
path_match": "name.*",
"path_unmatch": "*.middle",
"mapping":{
"type": "test",
"copy_to": "full_name"
}
}
}
]
}
}
```
抽象&类比
index
type
doc
dsl
文档
CURL
-
_Create
PUT users/_create/1 { ... }
POST users/_doc { }
id存在则不会进行index
-
_GET
GET users/_doc/1
-
Index
PUT users/_doc/1 { ... }
id存在,旧文档会被删除,version+1
-
Update
POST users/_update/1 { }
-
bulk
POST _bulk {"index": {"_index" : "test"}} {"index": {"_index" : "test2"}} {"index": {"_index" : "test3"}}
_mget
_msearch
error
- 429 -> 集群繁忙
- 4xx -> 请求格式错误
- 500 -> 集群错误
索引
index
shard
mapping 字段定义
settings shard分布
节点
- Data Node
- Coordinating
Master 节点
- 所有节点信息
- 所有索引和相关mapping和setting信息
- 分片路由信息
分片
-
主分片
- 一个分片 - Lucene实例
1.创建索引时制定
number_of_shards
- 一个分片 - Lucene实例
副本
number_of_replicas
设定
主分片过小: 限制水平扩展
主分片过大: over-sharding
健康状态
- green
- yellow - 主分片分配完成,副本未分配完成
- red - 主分片未分配完成
_cat/cluster/health
_cat/shards
Search Template
```curl
POST _script/test
{
...
}
```
Index Alias
```curl
POST _aliases
{
"actions":[
{
"add":{
"index":"index", //要引用的index
"alias":"alias_index",//index别名
"filter":{
...
}
}
}
]
}
```
Index Request
一个分片(shard) == Lucene Index
Segment1 Segment2 Segment3
| | |
|------|---------|
v
commit Point .del
1)客户端发起数据写入请求,对你写的这条数据根据_routing规则选择发给哪个Shard。
1. 确认Index Request中是否设置了使用哪个Filed的值作为路由参数,
1. 如果没有设置,则使用Mapping中的配置,
1. 如果mapping中也没有配置,则使用_id作为路由参数,然后通过_routing的Hash值选择出Shard,最后从集群的Meta中找出出该Shard的Primary节点。
2)写入请求到达Shard后,先把数据写入到内存(buffer)中,同时会写入一条日志到translog日志文件中去。
1. 当写入请求到shard后,首先是写Lucene,其实就是创建索引。
1. 索引创建好后并不是马上生成segment,这个时候索引数据还在缓存中,这里的缓存是lucene的缓存,并非Elasticsearch缓存,lucene缓存中的数据是不可被查询的。
3)执行refresh操作:从内存buffer中将数据写入os cache(操作系统的内存),产生一个segment file文件,buffer清空。
1. 写入os cache的同时,建立倒排索引,这时数据就可以供客户端进行访问了。
1. 默认是每隔1秒refresh一次的,所以es是准实时的,因为写入的数据1秒之后才能被看到。
1. buffer内存占满的时候也会执行refresh操作,buffer默认值是JVM内存的10%。
1. 通过es的restful api或者java api,手动执行一次refresh操作,就是手动将buffer中的数据刷入os cache中,让数据立马就可以被搜索到。
1. 若要优化索引速度, 而不注重实时性, 可以降低刷新频率。
4)translog会每隔5秒或者在一个变更请求完成之后,将translog从缓存刷入磁盘。
1. translog是存储在os cache中,每个分片有一个,如果节点宕机会有5秒数据丢失,但是性能比较好,最多丢5秒的数据。。
1. 可以将translog设置成每次写操作必须是直接fsync到磁盘,但是性能会差很多。
1. 可以通过配置增加transLog刷磁盘的频率来增加数据可靠性,最小可配置100ms,但不建议这么做,因为这会对性能有非常大的影响。
5)每30分钟或者当tanslog的大小达到512M时候,就会执行commit操作(flush操作),将os cache中所有的数据全以segment file的形式,持久到磁盘上去。
1. 第一步,就是将buffer中现有数据refresh到os cache中去。
1. 清空buffer 然后强行将os cache中所有的数据全都一个一个的通过segmentfile的形式,持久到磁盘上去。
1. 将commit point这个文件更新到磁盘中,每个Shard都有一个提交点(commit point), 其中保存了当前Shard成功写入磁盘的所有segment。
把translog文件删掉清空,再开一个空的translog文件。
1. flush参数设置:
1. index.translog.flush_threshold_period:
1. index.translog.flush_threshold_size:
1. #控制每收到多少条数据后flush一次
1. index.translog.flush_threshold_ops:
6)Segment的merge操作:
1. 随着时间,磁盘上的segment越来越多,需要定期进行合并。
1. Es和Lucene 会自动进行merge操作,合并segment和删除已经删除的文档。
1. 我们可以手动进行merge:POST index/_forcemerge。一般不需要,这是一个比较消耗资源的操作。
Shrink & Rollover
时间序列的索引
Hot -> Warm -> Cold -> Delete
Curator
ILM
Index Lifecycle Policy
Poliy
PUT /_iml/policy/log_ilm_policy
{
"policy":{
"phases":{
"hot"
"warm"
"cold"
"delete"
}
}
}
Hot -> Warm -> Cold -> Delete