22.es各操作实现原理
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了22.es各操作实现原理相关的知识,希望对你有一定的参考价值。
参考技术A 新建、索引和删除请求都是写(write)操作,它们必须在主分片上成功完成才能复制到相关的复制分片上。下面我们罗列在主分片和复制分片上成功新建、索引或删除一个文档必要的顺序步骤:
客户端接收到成功响应的时候,文档的修改已经被应用于主分片和所有的复制分片。你的修改生效了。
有很多可选的请求参数允许你更改这一过程。你可能想牺牲一些安全来提高性能。这一选项很少使用因为Elasticsearch已经足够快,不过为了内容的完整我们将做一些阐述。
复制默认的值是sync。这将导致主分片得到复制分片的成功响应后才返回。
如果你设置replication为async,请求在主分片上被执行后就会返回给客户端。它依旧会转发请求给复制节点,但你将不知道复制节点成功与否。
上面的这个选项不建议使用。默认的sync复制允许Elasticsearch强制反馈传输。async复制可能会因为在不等待其它分片就绪的情况下发送过多的请求而使Elasticsearch过载。
文档能够从主分片或任意一个复制分片被检索。
下面我们罗列在主分片或复制分片上检索一个文档必要的顺序步骤:
对于读请求,为了平衡负载,请求节点会为每个请求选择不同的分片——它会循环所有分片副本。
可能的情况是,一个被索引的文档已经存在于主分片上却还没来得及同步到复制分片上。这时复制分片会报告文档未找到,主分片会成功返回文档。一旦索引请求成功返回给用户,文档则在主分片和复制分片都是可用的。
update API 结合了之前提到的读和写的模式。
下面我们罗列执行局部更新必要的顺序步骤:
update API还接受《新建、索引和删除》章节提到的routing、replication、consistency和timout参数。
当主分片转发更改给复制分片时,并不是转发更新请求,而是转发整个文档的新版本。记住这些修改转发到复制节点是异步的,它们并不能保证到达的顺序与发送相同。如果Elasticsearch转发的仅仅是修改请求,修改的顺序可能是错误的,那得到的就是个损坏的文档。
mget和bulk API与单独的文档类似。差别是请求节点知道每个文档所在的分片。它把多文档请求拆成每个分片的对文档请求,然后转发每个参与的节点。
一旦接收到每个节点的应答,然后整理这些响应组合为一个单独的响应,最后返回给客户端。
下面我们将罗列通过一个mget请求检索多个文档的顺序步骤:
routing 参数可以被docs中的每个文档设置。
下面我们将罗列使用一个bulk执行多个create、index、delete和update请求的顺序步骤:
bulk API还可以在最上层使用replication和consistency参数,routing参数则在每个请求的元数据中使用。
ElasticSearcho从入门到放弃:操作, 编程, 架构原理, ES SQL
文章目录
一、操作:
1. 创建索引
为了能够搜索数据, 需要提前在ES中创建索引, 然后才能进行关键字的检索;
在ES中, 也可以使用mysql中创建一个表, 指定表名, 列, 列属性的方式;
1.1 创建带有映射的索引:
ES中, 可以使用RESTful APi来进行索引的各种操作;
创建mysql表时, 使用DDL来描述表结构, 字段, 字段类型,约束等; 在ES中, 使用DSL来定义
PUT /mysql-index
"mappings":
"properties"
"employee-id":
"type": "keyword",
"index": false
1.2 字段类型
分类 | 类型名称 | 说明 |
---|---|---|
简单类型 | text | 需要进行全文检索的字段; 通常使用text类型来对应邮件正文、产品描述或短文等非结构化文本数据; 分词器先会将文本进行分词转换为词条列表; 将来就可以基于词条进行检索了; 文本字段不能用户排序, 也很少聚合计算; |
keyword | 使用keyword来对应结构化的数据, 如ID,、电子邮件地址、主机名、状态码、标签等; 可以使用keyword来进行排序和聚合计算; 注意: keyword是不能进行分词的; | |
long/integer/short/byte | 64位整数/32位整数/16位整数/8位整数 | |
double | float | |
boolean | true / false | |
ip | Ipv4 / ipv6 | |
json分层嵌套类型 | object | 用于保存json对象 |
nested | 用于保存json数组 | |
特殊类型 | geo_point | 用于保存经纬度坐标 |
geo_shape | 用于保存地图上多边形坐标 |
1.3 创建保存"职位"信息的索引
ps: 判断使用text还是keyword, 主要看是否需要分词
字段 | 说明 | 类型 |
---|---|---|
doc_id | 唯一标识(作为文档ID) | keyword |
area | 职位所在区域 | keyword |
exp | 岗位要求的工作经验 | text |
edu | 学历要求 | keyword |
salary | 薪资范围 | keyword |
job_type | 职位类型(全职/兼职/实习) | keyword |
cmp | 公司名 | text |
pv | 浏览量 | keyword |
title | 岗位名称 | text |
jd | 职位描述 | text |
PUT /job_idx
"mappings":
"properties":
"area": "type": "text", "store": true ,
"exp": "type": "text", "store": true ,
"edu": "type": "keyword", "store": true ,
"salary": "type": "keyword", "store": true ,
"job_type": "type": "keyword", "store": true ,
"cmp": "type": "text", "store": true ,
"pv": "type": "keyword", "store": true ,
"title": "type": "text", "store": true ,
"jd": "type": "text", "store": true
result:
"acknowledged": true,
"shards_acknowledged": true,
"index": "job_idx"
1.4 查看索引映射
使用Get请求查看索引映射
GET /job_idx/_mapping
result:
"job_idx":
"mappings":
"properties":
"area":
"type": "text",
"store": true
,
"cmp":
"type": "text",
"store": true
,
"edu":
"type": "keyword",
"store": true
,
"exp":
"type": "text",
"store": true
,
"jd":
"type": "text",
"store": true
,
"job_type":
"type": "keyword",
"store": true
,
"pv":
"type": "keyword",
"store": true
,
"salary":
"type": "keyword",
"store": true
,
"title":
"type": "text",
"store": true
1.5 查看ES中素有索引
GET _cat/indices
result:
1.6 删除索引
DELETE /job-idx
result:
"acknowledged": true
1.7 指定使用IK分词器
因为存放在索引库中的数据, 是以中文的形式存储的, 所以, 使用Ik分词器
PUT /job_idx
"mappings":
"properties":
"area": "type": "text", "store": true, "analyzer": "ik_max_word" ,
"exp": "type": "text", "store": true, "analyzer": "ik_max_word" ,
"edu": "type": "keyword", "store": true ,
"salary": "type": "keyword", "store": true ,
"job_type": "type": "keyword", "store": true ,
"cmp": "type": "text", "store": true, "analyzer": "ik_max_word" ,
"pv": "type": "keyword", "store": true ,
"title": "type": "text", "store": true, "analyzer": "ik_max_word" ,
"jd": "type": "text", "store": true, "analyzer": "ik_max_word"
2. 使用PUT添加一条数据
在es中, 每一个文档都有唯一的ID, 也是使用json格式来描述数据的;
PUT /customer/_doc/1
"name": "John"
- 如果在costomer中, 不存ID为1的文档, ES会自动创建
2.1 添加一条职位信息
PUT /job_idx/_doc/29097
"area": "深圳-南山区",
"exp": "一年经验",
"edu": "本科及以上",
"salary": "8-12K/月",
"job_type": "实习",
"cmp": "乐有家",
"pv": "618万人浏览过/14人评价/113人正在关注",
"title": "桃园 深大销售实习 岗前培训",
"jd": "这是一个 桃园 深大销售实习 岗前培训的职位描述, 一些乱七八在的说明, 我没有文档, 懒得手打了"
result:
"_index": "job_idx",
"_id": "29097",
"_version": 1,
"result": "created",
"_shards":
"total": 2,
"successful": 1,
"failed": 0
,
"_seq_no": 0,
"_primary_term": 1
3 修改数据
3.1 执行update操作
POST /job_idx/29097
"doc":
"salary": "80-120k/月"
result:
"_index": "job_idx",
"_id": "29097",
"_version": 2,
"result": "updated",
"_shards":
"total": 2,
"successful": 1,
"failed": 0
,
"_seq_no": 1,
"_primary_term": 1
4. 删除操作
DELETE /job_idx/_doc/29097
result:
"_index": "job_idx",
"_id": "29097",
"_version": 2,
"result": "updated",
"_shards":
"total": 2,
"successful": 1,
"failed": 0
,
"_seq_no": 1,
"_primary_term": 1
5. 批量导入json数据
5.1 bulk导入:
es提供了bulk接口, 用来批量导入json文件中的数据
curl -H "Content-Type:application/json" -XPOST "localhost:9200/job_idx/bulk?pretty&refresh" --data-binary "@job_info.json"
6. 查看索引状态
GET /_cat/indices?index=job_idx
7. 检索:
7.1 根据ID检索数据
GET /job_idx/_search
"query":
"ids":
"values": ["29097"]
result:
"took": 47,
"timed_out": false,
"_shards":
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
,
"hits":
"total":
"value": 1,
"relation": "eq"
,
"max_score": 1.0,
"hits": [
"_index": "job_idx",
"_id": "29097",
"_score": 1.0,
"_source":
"area": "深圳-南山区",
"exp": "一年经验",
"edu": "本科及以上",
"salary": "80-120k/月",
"job_type": "实习",
"cmp": "乐有家",
"pv": "618万人浏览过/14人评价/113人正在关注",
"title": "桃园 深大销售实习 岗前培训",
"jd": "这是一个 桃园 深大销售实习 岗前培训的职位描述, 一些乱七八在的说明, 我没有文档, 懒得手打了"
]
7.2 根据关键字搜索
检索jd中"销售"相关的岗位
GET /job_idx/_search
"query":
"match":
"jd": "销售"
result:
"took": 49,
"timed_out": false,
"_shards":
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
,
"hits":
"total":
"value": 1,
"relation": "eq"
,
"max_score": 0.2876821,
"hits": [
"_index": "job_idx",
"_id": "29097",
"_score": 0.2876821,
"_source":
"area": "深圳-南山区",
"exp": "一年经验",
"edu": "本科及以上",
"salary": "80-120k/月",
"job_type": "实习",
"cmp": "乐有家",
"pv": "618万人浏览过/14人评价/113人正在关注",
"title": "桃园 深大销售实习 岗前培训",
"jd": "这是一个 桃园 深大销售实习 岗前培训的职位描述, 一些乱七八在的说明, 我没有文档, 懒得手打了"
]
7.3 根据关键分页搜索
在存在大量数据时, 一般进行查询都需要进行分页查询;
7.3.1 使用from和size来进行分页
在执行查询时, 可以指定from(从第n个开始)和size(每页返回多少条)来完成分页
GET /job_idx/_search
"from": 0,
"size": 5,
"query":
"multi_match":
"query": "销售",
"fields": ["title", "jd"]
ps:
- from = (page-1) *size
7.3.2 使用scroll方式进行分页
使用from和size方式, 查询1w-5w条数据以内是ok的, 但是, 如果数据比较多的时候, 会出现性能问题; ES做了一个限制, 不允许查询超过1w条以后的数据, 如果要查询, 需要使用ES中提供的scoll(游标)来查询;
在进行大量分页时, 每次分页都需要将要查询的数据进行重新排序, 这样非常浪费性能;
使用scoll是将要用的数据一次性排序好, 然后分批取出; 性能要比from+size好很多;
使用scroll查询后, 排序后数据会保持一段时间, 后续分页查询都从该快照取数据;
使用scoll是为了解决深分页的性能问题
第一次使用scroll分页查询
此处, 让排序数据保持1分钟
GET /job_idx/_search?scroll=1m
"size": 100,
"query":
"multi_match": // 检索多个字段
"query": "销售",
"fields": ["title", "jd"]
result:
"_scroll_id": "FGluY2x1ZGVfY29udGV4dF91dWlkDXF1ZXJ5QW5kRmV0Y2gBFk9TSmltZ2kxU1hlbHVJcHd3dEphUXcAAAAAAAAAWBY1Ymo4VGlzclI4V0dzc0x6aXZsczNR",
"took": 29,
"timed_out": false,
"_shards":
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
,
"hits":
"total":
"value": 1,
"relation": "eq"
,
"max_score": 0.2876821,
"hits": [
"_index": "job_idx",
"_id": "29097",
"_score": 0.2876821,
"_source":
"area": "深圳-南山区",
"exp": "一年经验",
"edu": "本科及以上",
"salary": "80-120k/月",
"job_type": "实习",
"cmp": "乐有家",
"pv": "618万人浏览过/14人评价/113人正在关注",
"title": php实现日志管理(记录用户操作)原理