elasticSearch核心知识

本文是根据【中华石杉】Elasticsearch顶尖高手系列-核心知识篇课程记录的笔记,可以在百度脑图中查看思维导图版本

链接 http://naotu.baidu.com/file/e32c27efdcec4c7fc8d127fe21a0703d?token=da437ea5ca4a43ea

elasticSearch核心知识

1.白话解释es

 1. 分布式,高性能,高可用,可伸缩的搜索和分析系统

2. 什么是搜索

3. 如果在数据库搜索会怎么样

数据量大时性能差

不能支持特殊查询,比如将词语分开

4. 全文搜索和Lucene

2. es功能,适用场景及特点

1. 分布式搜索引擎和数据分析引擎

1. 搜索

1. 全文检索
搜索商品名称中包含“日化”的商品
2. 结构化检索
搜索商品分类为日用品的商品
3.数据分析
查询每个商品分类下商品的个数

2. 分布式

对海量数据进行近实时的处理

分布式:可以将海量数据分散到多台机器存储和检索

2. 适用场景

国外

1. 维基百科
2.新闻网站
用户行为日志(点击,浏览,收集,评论)
stack overflow
github
搜索上千亿行代码
电商网站
搜索商品
日志数据分析
elk,logstash采集日志,es进行数据分析
商品价格监控网站
BI系统

国内

站内搜索
电商
招聘
门户
数据分析

特点

1,可以作为一个大型分布式集群,处理pb级的数据

2. es是将全文检索,数据分析,分布式技术结合大一起的

3. 开箱即用,非常简单

4,数据库的不擅长的领域,例如全文检索,同义词处理,相关度

3. 核心概念

1.index

索引,相当于数据库中库

2. type

类型,相当于数据库中的表

3. document

文档,相当于数据库中一行数据

4. 常用概念

1. NRT

near real time
准实时查询,秒级

2.集群

3.节点

4.分片

primary shard
将数据分片,提高吞吐量
primary shard和replic shard
1.index包含多个shard
2.每个shard都是最小的工作单元,承载部分数据,是一个lucene实例,拥有完整的数据处理能力
3. 增减节点时,shard会自动在node中负载均衡
4. 每个document肯定存在并且仅存在一个primaryshard中
5. replic shard是primary shard的副本,负责容错以及分担读请求负载
6.primary shard的数量在创建索引时就固定了,replic shard的数量可以随时修改
7.primary shard 默认数量是5,replic shard 默认数量是1
8.primary shard不能和自己的replic shard保存在同一个节点,但可以和其他primary shard的副本保存在同一个节点上
修改primary shard和replic的数量
PUT /test_index

{
“settings” : {
“number_of_shards” : 3,
“number_of_replicas” : 1
}
}

5.副本

replica shard
作为primary复制集存在,实现高可用,必须和primaryshard在不同的机器上

5.es分布式相关的一些问题

1.es利用分布式的方式解决大数据量问题,将数据分布到不同节点去执行操作,对机器的IO,CPU等要求降低

2.es将负责的分布式细节隐藏

1.分片机制
es自动分片不需要人为干预,我们不需要了解es是怎么分片,也不需要数据被分配到哪个shard
2.集群发现机制 cluster discovery
当有新节点加入集群时,集群会自动分配shard,并将数据存入新节点
3. shard负载均衡
其他
shard副本
请求路由
集群扩容

####### 集群扩容时,只会增加replic shard,primy shard个数不能改变

shard重分配
增加或删除节点时,数据rebalance

3.节点平等的分布式架构

1.节点对等,每个节点都能处理所有请求
2. 自动路由请求
将请求路由到存在符合条件的shard上
响应收集

4. 路由规则

1. 路由规则用来确定document被存储到那个shard上
2. 路由规则公式  shard= hash(routing)%num_of_shard
1.即先对roting参数进行hash,然后在对primary shard的个数求余
2. routing参数默认为document的ID,也可以手动指定

####### PUT /index/type/id?routing=ssid

手动指定routing参数可以将特定的数据路由到指定的shard上方便后续操作
primary shard不可以更改的原因
更改primary shard后,通过路由规则会路由到不同的shard上,造成数据“丢失”

6.扩容

扩容分类

1.垂直扩容
提供机器配置

####### 价格昂贵

2. 水平扩容
将普通服务器组织在一起,构成强大的计算能力和存储能力

####### 业内经常采用

扩容对应用程序透明

7.容错

8. timeout超时机制

1.默认是没有timeout的

2.在指定timeout后,每个shard会将在指定的时间内将已查询出来的数据返回给客户端

3. timeout机制可以对一些时间敏感的查询有很大帮助

9. mapping(域映射)

1. 为了将时间域视为时间,数字域视为数字,字符串域视为字符串

即es需要知道各个filed中数据类型创建了filed

2. 如果不手动指定,es会自动创建mapping(dynamic mapping)

3. mapping 一旦创建无法修改

4. 查看mapping

1. 查看index下所有type的mapping
GET /test_index/_mapping
2. 查看指定type的mapping
GET /test_index/_mapping/test_type

5. 自定义域映射

1.自定义域映射的优势
1. 可以指定字符串字段是按全文搜索还是用精确搜索
2.可以指定特定语言分词器
3. 优化域以适应部分匹配
2. 自定义mapping示例
PUT /website

{
“mappings”: {
“article”:{
“properties”: {
“title”:{
“type”: “text”,
“fields”: {
“raw”:{
“type”: “text”,
“index”: “not_analyzed”
}
},
“fielddata”: true
},
“content”:{
“type”: “text”
},
“post_date”:{
“type”: “date”
},
“author_id”:{
“type”: “long”
}
}
}
}
}

6.mapping复杂结构

1. mutivalue field
即数组类型的field

####### 如{tags:[“tag1″,”tag2”]}

2. empty field
null,[],[null]
3. object field
即一个字段是一个对象

####### object类型对属性在底层存储对格式

######## 1. “address”:{
“country”:”china”,
“provice”:”shandong”,
“city”:”jinan”
}

######### address.contry:[china]
address.provice:[shandong]
address.city:[jinan]

######## 2. authors:[      {age:18,name:”jack”},
{age:20,name:”tom”},]

######### authors.age:[18,20]
authors.name:[“jack”,”tom”]

10.分词器

1. 查看分词器是如何运行的

GET /_analyze

{
“analyzer”: “standard”,
“text”: “Text to analyze”
}

11. _validate验证查询是否正确

对一个写对很长对查询进行校验

12. 相关度评分算法TF&IDF

1. term frequency/inverse document frequency算法,简称为TF/IDF算法

2. term frequency

表示要搜索的字符在文档中出现的频率,频率越高相关度越高

3. inverse document frequency

即要搜索的字符在所有文档出现的频次越高,相关度评分越低
举例说明,如果我要搜索“hello world”这个字符串,

“hello”在所有文档中出现了1000次,“world”在所有文档中出现了100次,
那么“world”这个出现时的权重就要比“hello”出现时的权重要高

4. Field-length norm:field长度,field越长,相关度越弱

5. 利用explian查看分数的计算规则

GET /test_index/test_type/_search?explain

{
“query”: {
“match”: {
“test_filed1”: “bulk”
}
}
}

计算规则在explian结果的details字段
结果示例

####### {
“took”: 4,
“timed_out”: false,
“_shards”: {
“total”: 5,
“successful”: 5,
“skipped”: 0,
“failed”: 0
},
“hits”: {
“total”: 2,
“max_score”: 0.62191015,
“hits”: [
{
“_shard”: “[test_index][2]”,
“_node”: “YOC7d_TiS-Oy53TD7JviVg”,
“_index”: “test_index”,
“_type”: “test_type”,
“_id”: “4”,
“_score”: 0.62191015,
“_source”: {
“test_filed1”: “bulk create”
},
“_explanation”: {
“value”: 0.6219102,
“description”: “weight(test_filed1:bulk in 0) [PerFieldSimilarity], result of:”,
“details”: [
{
“value”: 0.6219102,
“description”: “score(doc=0,freq=1.0 = termFreq=1.0\n), product of:”,
“details”: [
{
“value”: 0.6931472,
“description”: “idf, computed as log(1 + (docCount – docFreq + 0.5) / (docFreq + 0.5)) from:”,
“details”: [
{
“value”: 1,
“description”: “docFreq”,
“details”: []
},
{
“value”: 2,
“description”: “docCount”,
“details”: []
}
]
},
{
“value”: 0.89722675,
“description”: “tfNorm, computed as (freq * (k1 + 1)) / (freq + k1 * (1 – b + b * fieldLength / avgFieldLength)) from:”,
“details”: [
{
“value”: 1,
“description”: “termFreq=1.0”,
“details”: []
},
{
“value”: 1.2,
“description”: “parameter k1”,
“details”: []
},
{
“value”: 0.75,
“description”: “parameter b”,
“details”: []
},
{
“value”: 2,
“description”: “avgFieldLength”,
“details”: []
},
{
“value”: 2.56,
“description”: “fieldLength”,
“details”: []
}
]
}
]
}
]
}
},
{
“_shard”: “[test_index][1]”,
“_node”: “YOC7d_TiS-Oy53TD7JviVg”,
“_index”: “test_index”,
“_type”: “test_type”,
“_id”: “5”,
“_score”: 0.25811607,
“_source”: {
“test_filed1”: “bulk index”,
“test_filed2”: “bulk update”
},
“_explanation”: {
“value”: 0.25811607,
“description”: “weight(test_filed1:bulk in 0) [PerFieldSimilarity], result of:”,
“details”: [
{
“value”: 0.25811607,
“description”: “score(doc=0,freq=1.0 = termFreq=1.0\n), product of:”,
“details”: [
{
“value”: 0.2876821,
“description”: “idf, computed as log(1 + (docCount – docFreq + 0.5) / (docFreq + 0.5)) from:”,
“details”: [
{
“value”: 1,
“description”: “docFreq”,
“details”: []
},
{
“value”: 1,
“description”: “docCount”,
“details”: []
}
]
},
{
“value”: 0.89722675,
“description”: “tfNorm, computed as (freq * (k1 + 1)) / (freq + k1 * (1 – b + b * fieldLength / avgFieldLength)) from:”,
“details”: [
{
“value”: 1,
“description”: “termFreq=1.0”,
“details”: []
},
{
“value”: 1.2,
“description”: “parameter k1”,
“details”: []
},
{
“value”: 0.75,
“description”: “parameter b”,
“details”: []
},
{
“value”: 2,
“description”: “avgFieldLength”,
“details”: []
},
{
“value”: 2.56,
“description”: “fieldLength”,
“details”: []
}
]
}
]
}
]
}
}
]
}
}

6.查看某个文档是怎么匹配上的

GET /test_index/test_type/4/_explain

{
“query”: {
“match”: {
“test_filed1”: “bulk”
}
}
}

13. 正序索引

1.在建立索引的时候,会同时建立倒序索引和正序索引

2. 倒序索引用于搜索,正序索引用于排序,过滤,聚合操作

正序索引即docs value

3. doc values一般存储到磁盘上,但当内存足够大时,es会将数据加载到内存中,提高性能

14. query phase和fetch phase

query phase

请求到达es时,协调节点会根据from和size参数计算出优先队列的大小,

然后将请求分发到各个shard,各shard将返回优先队列大小的数据ID到协调节点

fetch phase

协调节点获取到各shard返回的id后,会将所有数据整合排序,

再根据from和size参数取出需要的数据ID,
然后根据这些ID,通过mget去获取完整的数据

15. 底层数据存储方式

1.es底层利用luence的存储方式存储数据

每个index下的所有type共用所有的field
如果两个field相差很多的type被放到同一个index下,会有很多空值,性能会很差

es写入数据的流程

1. 基于lucene的写入
1. 写请求进入到es后会先将数据写入内存buffer
2. 当到达commit point将内存buffer中的数据提交到index segment中
3. 等待在os cache中的index segment被fsync强制刷到磁盘上
4. 被刷新到磁盘后,新的index sgement被打开,供search使用
5. 清除内存buffer
6. 删除文件时,会生成一个.del文件记录被删除的记录,

当有查询时如果在.del文件中发现记录,则该记录不会被加入到返回的结果中

2. 优化措施
1. 在写入os cache就可以对外提供查询
2. 数据写入内存buffer的同时写入到translog中,确保数据的可用性

####### 1. 数据写入buffer缓冲和translog日志文件

####### 2.每隔一秒钟,buffer中的数据被写入新的segment file,并进入os cache,此时segment被打开并供search使用

####### 3.buffer被清空

####### 4. 重复1~3,新的segment不断添加,buffer不断被清空,而translog中的数据不断累加

####### 5. 当translog长度达到一定程度的时候,commit操作发生

######## 1.buffer中的所有数据写入一个新的segment,并写入os cache,打开供使用

######## 2. buffer被清空

######## 3. 一个commit ponit被写入磁盘,标明了所有的index segment

######## 4. filesystem cache中的所有index segment file缓存数据,被fsync强行刷到磁盘上

######## 5. 现有的translog被清空,创建一个新的translog

####### 6. 流程图

3. merge segment

####### 1.每秒一个segment file,文件过多,而且每次search都要搜索所有的segment,很耗时
默认会在后台执行segment merge操作,在merge的时候,被标记为deleted的document也会被彻底物理删除

####### 2. merge操作的执行流程

######## (1)选择一些有相似大小的segment,merge成一个大的segment

######## (2)将新的segment flush到磁盘上去

######## (3)写一个新的commit point,包括了新的segment,并且排除旧的那些segment

######## (4)将新的segment打开供搜索

######## (5)将旧的segment删除

3. 其他知识点
1.数据写入os cache,并被打开供搜索的过程,叫做refresh,默认是每隔1秒refresh一次。

也就是说,每隔一秒就会将buffer中的数据写入一个新的index segment file,先写入os cache中。
所以,es是近实时的,数据写入到可以被搜索,默认是1秒。

16. es的分析器配置

1. 分析器由3部分组成

1.字符过滤器(char_filter)
过滤特殊字符,如html字符
2. 分词器(Tokenizer)
分词器用来将文本分割为单独的词条
3. token过滤器 (filter)
删除没有的停词,大小写转换,同义词转换

2.怎么创建analyzer

1.  es可以在创建index的同时创建analyzer,并在mapping中设置analyzer
2. 也可以在elasticsearch.yml配置文件中定义analyzer

17.定制dynmic mapping策略

1.可选值

true
遇到陌生字段,就进行dynamic mapping
false
遇到陌生字段,就忽略
strict
遇到陌生字段就报错

2. 使用示例

PUT /my_index

{
“mappings”: {
“my_type”: {
“dynamic”: “strict”,
“properties”: {
“title”: {
“type”: “text”
},
“address”: {
“type”: “object”,
“dynamic”: “true”
}
}
}
}
}

此时如果想子该type下增加一个新字段就会报错,但是在address下增加一个新字段是可以的

3. 定制自己的dynamic mapping template(type level)

PUT /my_index

{
“mappings”: {
“my_type”: {
“dynamic_templates”: [
{ “en”: {
“match”:              “*_en”,
“match_mapping_type”: “string”,
“mapping”: {
“type”:           “string”,
“analyzer”:       “english”
}
}}
]
}}}

此时如果这个type的字段名称中包含“_en”

这个字符串就会使用english分词器,否则使用默认的分词器

4.定制自己的default mapping template(index level)

PUT /my_index

{
“mappings”: {
default“: {
“_all”: { “enabled”:  false }
},
“blog”: {
“_all”: { “enabled”:  true  }
}
}
}

此时my_index下的type除了“blog”这个type,其他的type

都不会有_all字段

4.基础操作

1. 查看es状态

get /_cat/health?v

green:每个索引的primary shard和replica shard都是active状态的

yellow:每个索引的primary shard都是active状态的,但是部分replica shard不是active状态,处于不可用的状态
red:不是所有索引的primary shard都是active状态的,部分索引有数据丢失了

2.查看有哪些索引

GET /_cat/indices?v

3.文档的基本操作

1. 创建索引

PUT /test_index?pretty
PUT /my_index

{
“settings”: {
“number_of_shards”: 1,
“number_of_replicas”: 0
},
“mappings”: {
“my_type”: {
“properties”: {
“my_field”: {
“type”: “text”
}
}
}
}
}

2. 删除索引

delete /test_index?pretty
delete /test_*
*号匹配删除索引
删除多个索引
delete /test_index1,test_index2
删除所有索引
delete /_all

3. 修改索引设置

PUT /my_index/_settings

{
“number_of_replicas”: 1
}

3. 文档操作

1. 新建
指定ID

####### PUT /index/type/id
{
“json数据”
}

es自动生成ID

####### post /ecommerce/product/
{
“name” : “yunnanbaiyao yagao”,
“desc” :  “caoben zhiwu”,
“price” :  40,
“producer” :      “zhonghua producer”,
“tags”: [ “zhongyao” ]
}

2.修改
1. 替换文档

####### put /index/type/id
{
完整的json数据
}

2. 更新文档,partial update

####### POST /index/type/id/_update
{
“doc”:{
“指定字段”:”值”
}
}

####### 在es中也会先把文档查询出来,再进行修改

######## 和全量替换对比

######### 1. 全量替换需要再程序中先查询出来,
然后再在es中删除老版本的数据,
最后创建新版本的数据,
partial update查询及删除操作时es自动执行的

######### 2.partial update相对于全量替换,所有的查询,删除,写回都在同一个shard中,减少了网络开销

######### 3. 由于partial update减少了查询和写回的时间差,所以可以减少并发冲突问题

####### 并发冲突处理

######## retry策略,retry_on_conflict指定重试次数

######### post /index/type/id/_update?retry_on_conflict=5&version=6

3. 查询
GET /index/type/id
GET  /index/_search?q=要搜索的关键字

####### 1.如果要搜索指定filed中的关键字

######## 1.GET /index/type/_search?q=+filed:keyword

######### 可以简写为 GET/index/type/_search?q=filed:keyword

######## 2.排除某个字段中某个关键词

######### GET /index/type/_search?q=-filed:keyword

####### _all元数据

######## es在创建文档时,会创建_all filed
它是由其他所有字段的值拼装出来的一个字符串

######### 当利用query Stirng查询时,
如果没有指定特定字段,则会查询每个document的_all字段

聚合查询

####### 1. 如果按照分词的字段进行聚合查询,需要把该字段fileddata设置为true

######## PUT /ecommerce/_mapping/product
{
“properties”: {
“tags”: {
“type”: “text”,
“fielddata”: true
}
}
}

######## 使用示例

######### GET /ecommerce/product/_search
{

“aggs”: {
“group_by_tag”: {
“terms”: {
“field”: “tags”
}
}
}
}

####### 2.如果按照不分词的字段聚合可以直接执行,不用设置fileddata 直接执行

####### 3. 使用.keyword进行聚合查询时,使用内置filed不分词,可以不设置fielddata

######## GET /ecommerce/product/_search
{

“aggs”: {
“group_by_tag”: {
“terms”: {
“field”: “producer.keyword”
}
}
}
}

复杂查询

####### 1.查询名字中有“yagao”的商品,并计算每个tag下的数量

######## GET /ecommerce/product/_search
{
“size”: 0,
“query”: {
“match”: {
“name”: “yagao”
}
},
“aggs”: {
“yagao_tag_group”: {
“terms”: {
“field”: “tags”,
“size”: 10
}
}
}
}

####### 2. 先按tag分组,再计算每个分组下价格的平均值,并按平均价格倒序排列

######## GET /ecommerce/product/_search
{
“size”: 0,
“aggs”: {
“group_by_tag”: {
“terms”: {
“field”: “tags”,”order”: {
“avg_price”: “desc”
}
}
, “aggs”: {
“avg_price”: {
“avg”: {
“field”: “price”
}
}
}
}
}
}

####### bool,must,must_not,should的使用

筛选要查找到字段

####### 使用_source参数

######## GET /test_index/test_type/1?_source=test_filed1,test_filed2

muti_index,muti_type 查询

####### 1. 对多个index查询

######## GET /my_index1,my_index2/type/_search

####### 2. 对多个type查询

######## GET /test_index/my_type,test_type/_search

####### 3.对多个index,多个type查询

######## GET /test_index,my_index/my_type,test_type/_search

####### 4. 通配符查询多个索引

######## GET /*_index/_search

######### 还有复杂正则表达式查询

####### 5._all查询

######## 查询所有的index下的数据

######### GET /_all/my_type/_search

分页查询

####### 1.分页查询基本语法

######## GET /test_index/test_type/_search?from=1&size=1

######### from是从哪一行数据开始查

######### size是每页多少条数据

####### 2.深度分页

######## 当查询第n页时,es会将每个shard前n页的数据全部查询出来,
然后返回给协调节点(coordinate node),
由coordinate node整理排序然后返回结果

######### 随着n越来越大,在各node和协调节点之间传输的数据越来越大,
并且占用协调节点的资源越来越多,因此查询性能会越来越差

4. 删除
DELETE /index/type/id

####### 执行delete命令指示把文档标记为“delete”状态,并未物理删除数据,
伴随着es中的数据越来越多,
es会自动删除“delete”状态的数据以节省空间

5. 文档增删改的内部原理
1. 客户端将请求发送到任一node节点,这个node就是协调节点(coordinating node)
2. 协调节点将请求发送到存储该document的primary shard
3. primary shard处理完后,将数据同步到replic
4. primary shard和repic shard同步结束后,协调节点响应客户端请求
6.一致性要求
1.在进行增删改操作时,对集群中数据的一致性要求,all,one,quorum

####### 1. one,只要在一个primary shard上操作成功即可

####### 2. all,要在所有的primary shard和replic shard上操作成功才可以

####### 3. quorum,在大部分的shard上操作成功才可以

######## 是默认的一致性要求

######### 计算公式:int((primary+replic)/2)+1

########## 只有在replic的数量大于1的时候适用

########### 如果活跃的shard数量少于quorum数量,则拒绝写操作,进行wait操作,默认wait1分钟,wait过后再次进行查询

########### 2. timeout,可以手动指定timeout时长,在timeout后,返回请求结果,防止wait时间过长

############ 1. GET /index/type/id?timeout=30s

2. consistency参数使用示例

####### PUT /index/type/id?consistency=quorum

6. 查询文档的内部原理
1. 客户端发送请求到任一个node,这个node就是coordinate node(协调节点)
2.协调节点,通过round-robin随机轮询,进行负载均衡,将请求发送的primary shard或者replic shard
3. 接收到请求的node,将查询到的document返回coordinate node,coordinate node将请求返回客户端
4. 特殊情况

####### document如果还在创建索引的过程中,可能只会存在于primary shard上,replic shard上没有数据,无法获取到documen

4. 全量替换

全量替换即使用put命令将原来的文档替换掉
在进行全量替换时,实际上是先将“老”数据标记为“delete”,然后重新创建文档
强制创建文档
不去替换原文档,而是创建新文档

当要创建的文档存在时,会报错

####### PUT /test_index/test_type/1/_create
{
“test_filed1″:”1234”,
“test_filed2″:”1234”
}

####### PUT /test_index/test_type/1?op_type=create
{
“test_filed1″:”1234”,
“test_filed2″:”1234”
}

5. groovy操作

1. es内置脚本支持,可以基于groovy进行各种复杂操作
2. 使用内部脚本
POST /test_index/test_type/11/_update

{
“script” : “ctx._source.num+=1”
}

3. 使用外部脚本
POST /test_index/test_type/11/_update

{
“script”: {
“lang”: “groovy”,
“file”: “test-add-tags”,
“params”: {
“new_tag”: “tag1”
}
}
}

####### 参数说明

######## lang:指定脚本为groovy脚本

######## file:指定脚本的名称,脚本需要放置到/elasticsearch/config/scripts/

######## params:指定脚本运行所需的参数

6. 文档的upsert操作

POST /test_index/test_type/11/_update

{
“script” : “ctx._source.num+=1”,
“upsert”: {
“num”: 0,
“tags”: []
}
}

如果指定文档不存在,则按upsert中的条件执行初始化,如果存在则执行script操作
POST /test_index/test_type/2/_update

{
“doc”: {
“test_filed1″:”11133”
}
, “upsert”: {
“test_filed1″:”upsert init ”
}
}

7.批量查询

批量查询可以减少网络开销,从而提高查询效率

1. 查询不同index中的数据
1. GET  /_mget{

“docs”:[
{
“_index”:”test_index”,
“_type”:”test_type”,
“_id”:”1″
},
{
“_index”:”test_index”,
“_type”:”test_type”,
“_id”:”2″
}

]
}

2.查询同一index下不同type的数据
GET /test_index/_mget

{
“docs”:[
{
“_type”:”test_type”,
“_id”:1
}
]
}

3.查询同一index,同一type下的数据
GET /test_index/test_type/_mget

{
“ids”:[1,2]
}

8.bulk操作

1. bulk可以批量进行多种操作
2. bulk的基本语法
POST /_bulk

{“action”: {“metadata”}}
{“data”}

示例

####### POST /_bulk
{ “delete”: { “_index”: “test_index”, “_type”: “test_type”, “_id”: “3” }}
{ “create”: { “_index”: “test_index”, “_type”: “test_type”, “_id”: “12” }}
{ “test_field”:    “test12” }
{ “index”:  { “_index”: “test_index”, “_type”: “test_type”, “_id”: “2” }}
{ “test_field”:    “replaced test2” }
{ “update”: { “_index”: “test_index”, “_type”: “test_type”, “_id”: “1”, “_retry_on_conflict” : 3} }
{ “doc” : {“test_field2” : “bulk test1”} }

3. bulk可执行的操作
1. delete,删除一个文档
2. create,强制创建,相当于put /index/type/id/_create
3. index ,普通的put操作,可以创建文档,也可以全量替换,相当于 put /index/type/id
4. update, partial update操作
4. 特别注意
1. bulk 请求会把所有的请求加载到内存中,

如果数据量太大效率反而会下降,
因此需要选择合适的数据大小

####### 一般来说先选择1000–5000条数据开始,逐渐增加,
并且数据大小最好在5~15M

2. bulk对json格式有严格要求

####### 1. json格式必须在一行内,并且每个json通过回车键分割

######## 之所以对格式有严格要求,是因为如果在内存中操作时进行格式转换(json–>jsonArray),
消耗的内存空间会成倍增长,限定好格式后可以优化转换效率,减少gc操作

3 bulk操作中,如果有部分操作失败,

不会影响其他操作的执行,只会在返回的日志中显示错误信息

9.排序

sort关键字
使用示例
排序字段必须设置fielddate=true
PUT /website/_mapping/article

{
“properties”: {
“title”:{
“type”: “text”,
“fields”: {
“raw”:{
“type”: “text”
, “fielddata”: true
}
}

}
}
}

对string field排序
因为string字段会被分词所以排序不准确

####### 通常对解决方案是,将string建立两次索引,
一个用来分词,一个用来排序

######## PUT /website
{
“mappings”: {
“article”:{
“properties”: {
“title”:{
“type”: “text”,
“fields”: {
“raw”:{
“type”: “text”,
“index”: “not_analyzed”
}
},
“fielddata”: true
},
“content”:{
“type”: “text”
},
“post_date”:{
“type”: “date”
},
“author_id”:{
“type”: “long”
}
}
}
}
}

######### 在创建mapping时,指定一个fileds属性,属性中指定raw,
并且raw是不分词的,查询时指定用raw排序

########## GET /website/article/_search
{
“query”: {
“match_all”: {}
},
“sort”: [
{
“title.raw”: {
“order”: “desc”
}
}
]
}

10. filter和query

filter是纯过滤查询,没有按分值排序

4. scoll技术查询大量数据

1. 比如要查询10万条数据,使用深度分页性能太差

2.使用scoll技术每次只返回指定size的数据,下一次可以根据scoll_id继续查询

3.使用方式

2. GET /_search/scroll{

“scroll”:”1m”,
“scroll_id”:”DnF1ZXJ5VGhlbkZldGNoBQAAAAAAB0WXFllPQzdkXn”
}

在第二步查询时可以直接指定scroll_id,而不必像上一步一样指定各种查询条件

es可以根据scroll_id获取到上一步指定的查询条件

1. GET /test_index/test_type/_search?scroll=1m{

“query”: {
“match_all”: {}
},
“sort”: [ “_doc” ],
“size”: 1
}

第一步指定scoll=1m,表示要在一分钟内进行下一次查询

查询结束后除了要查询的结果,还会返回一个scoll_id用于第二步查询

5. es中的并发处理

1. 锁的分类

1.悲观锁

常见于关系型数据库,如mysql

2. 乐观锁

cas

2. es中乐观锁的使用

_version元数据

新建文档时version为1,每次修改,删除都会对version加1
使用方式
PUT /test_index/test_type/7?version=1

{
“test_field”: “test client 1”
}

####### 当指定的version与es中的version不同时,则更新失败

externail version

es提供的一个特性
可以不基于es中的version,而是基于自己控制的version进行修改,删除
使用方式

####### PUT /test_index/test_type/7?version=1&version_type=externail
{
“test_field”: “test client 1”
}

######## 当指定的version比es中的version大时才可以修改成功

6.常见问题

1. bouncing result问题

(结果跳跃问题)

1.问题描述:因为请求是通过随机轮询的方式在各shard上处理的,

两次相同的请求得到的结果顺序有可能会不同,
如果相同的请求返回给用户的结果顺序是不同,就会对用户造成困扰

2. 问题解决:使用preference参数指定要查询的shard

preference参数的可选值
1. primary
2. primary_first
3. _local
4.only_node:xyz

####### 在特定node上查询

5. _prefer_node:xyz
6._shard:2,3

2. 利用scroll技术和别名进行零停机数据迁移

创作不易,转载请注明文章来源为www.full-satcker.com:邢桂帅 » elasticSearch核心知识

赞 (0)
分享到:更多 ()

相关推荐

    暂无内容!

评论 0

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址