欢迎访问我的博客,你的支持,是我最大的动力!

elasticsearch技术解析与实战(一) 入门和索引

ELK Stack 小马奔腾 9714℃ 评论
目录:
[显示]

本文是《Elasticsearch技术解析与实战》的笔记,该书基于es2.3.0

Elasticsearch入门

Lucene倒排索引,根据属性值来查找记录,inverted index。lucene在实现中,使用词典文件、频率文件和位置文件来保存倒排索引。词典文件中除了关键词,还有到频率文件和位置文件的指针。

Elasticsearch的术语及概念

索引词term:能够被索引的精确值,索引词可以通过term查询进行准确搜索
文本text:一段普通的非结构化文字,通常文本会被分析成一个个的索引词
分析analysis:将文本转换为索引词的过程,依赖于分词器
集群cluster:一个或多个节点组成,对外提供服务;节点node
路由routing:确定文档存储于哪个主分片中
分片shard:分片是单个lucene实例,每个分片是一个全功能的、独立的单元,可以托管在集群中的任何节点
主分片primary shard:默认一个索引有5个主分片,索引一但建立,分片数量不能修改;副分片replica shard:主分片的复制,增加高可用性、提高性能、允许水平扩展、允许并行操作,查询可以在主分片或者副本分片中进行,默认一个主分片会有一个副本分片,但是可以动态设置,但副本分片必须部署在不同的节点上,不能部署于和主分片相同的节点上
复制replica:可以实现故障转移,保证系统高可用
索引index:具有相同结构的文档集合
类型type:在索引中,可以定义一个或者多个类型,类型是索引的逻辑分区
文档document:一条记录,json格式的字符串。原始的json文档被存储在_source字段中
映射mapping:类似于表结构,定义每个索引中每一个字段类型,可以事先定义或者第一次存储时自动识别
字段field:每个字段都有字段类型,如整数、字符串等,字段还可以指定如何时分析该字段的值
来源字段source field:存储原始对象,不显示索引分析后的其他任何数据
主键ID:一个文件的唯一标识,文档的index/type/id必须唯一

elasticsearch部署时,建议-Xmx最大可以使用内存设置为物理内存的一半,同时,Mms和Xmx初始内存和最大内存相同,这样可以减少动态内存分配的消耗。默认的配置文件在elasticsearch/bin/elasticsearch.in.sh中,也可以通过设置ES_HEAP_SIZE环境变量进行配置,最大值和最小值可以通过配置ES_MIN_MEM和ES_MAX_MEM来设置。

配置文件:

如果机器上只运行一个集群节点,节点名可以使用${HOSTNAME}设置节点名为主机名
action.destructive_requires_name:true当删除一个索引时,需要指定具体索引的名称
index.refresh_interval:5s配置该节点默认索引刷新间隔时间

集群关闭和重启:

1、关闭分片分配。因为当我们试图关闭一个节点时,es会立即试图复制这个节点的数据到集群中的其他节点,这将导致大量的IO请求,因此,在关闭节点时,可以设置关闭分片分配
PUT /_cluster/settings
{"transient":{"cluster.routing.allocation.enable":"none"}}
2、执行一个同步刷新。当停止一个索引时,分片的恢复会很快,所以要进行同步刷新请求
POST /_flush/synced
当任何索引操作失败的时候,都可以执行同步刷新请求,必要的时候可以执行多次
3、关闭这个节点
4、重新启动这个节点,如果专门有主节点(node.master为true,node.data为false),则先启动主节点
5、检查节点健康状态
GET _cat/health
GET _cat/nodes
刚开始为红色,当每个节点都恢复完成后,集群状态会变成黄色,意味着所有主分片已经被找到
6、重新分配。延迟副本的分配直到所有节点都加入集群,在集群的所有节点,可以重新启用分片分配
PUT /_cluster/settings
{"transient":{"cluster.routing.allocation.enable":"all"}}
这时集群将开始复制所有副本到数据节点上,这样可以安全的恢复索引和搜索,并加快集群恢复
7、检查集群恢复进度和健康状态
GET _cat/health
GET _cat/recovery
当状态变为绿色的时候,表时完成

对外接口

es对处提供HTTP服务,所有和HTTP配置相关的内容都是静态配置,意味着必须重启才可以生效,HTTP是可以禁止的,http.enabled设置为false。集群通信是通过内部接口实现,一般一个集群在一个节点上开启HTTP就可以。

API约定

多索引参数
_all表示全部索引,另外,也支持使用通配符,如*,同时也支持排除操作,+test*,-test3表示查询所有以test开头的索引,但排除test3
多索引查询还支持这些参数:ignore_unavailable当索引不存在或关闭时,是否忽略,值为true/false;allow_no_indices当有索引不存在时,是否返回查询失败,值为true/false;expand_wildcards控制通配符匹配范围,open只作用于开启状态的索引,close只作用于关闭状态的索引,none不可用,all同时支持open和close

日期筛选
语法:<static_name{date_math_expr{date_format|time_zone}}>
<索引名{动态日期计算表达式{日期格式|时区,默认UTC}}>
curl -XGET '127.0.0.1:9200/<logstash-{now/d-2d}>/_search' {"query":{...}}
日期计算表达:假如当前为2018.04.10
<logstash-{now/d}> 为logstash-2018.04.10
<logstash-{now/M}> 为logstash-2018.04.01
<logstash-{now/M{YYYY.MM}}> 为logstash-2018.04
<logstash-{now/M-1M{YYYY.MM}}> 为logstash-2018.03
<logstash-{now/d{YYYY.MM.dd|+08:00}}> 为logstash-2018.04.10
如果索引名包含{}可以通过添加\转义,如<elastic\\{ON\\}-{now/M}>会被转义为elastic{ON}-2018.04.10
可以用逗号选择多个时间,如选择最近三天可以这样写
curl -XGET '127.0.0.1:9200/<logstash-{now/d-2d}>,<logstash-{now/d-d}>,<logstash-{now/d}>/_search' {"query":{...}}

通用参数
pretty格式化后的json方便阅读?pretty=true 还可以输出为yaml格式 ?format=yaml
human对于统计数据,支持适合阅读的单位,会消耗更多资源,默认false 使用?human=true
日期表达式,格式化日期表达式,范围查询gt大于和lt小于,或者在日期聚合中用from to表达时间范围
表达式设定的日期为now或者日期字符串加||
+1h 增加一小时
-1D 减少一小时
/D上一个小时
支持单位:年y、月M、周w、日d、小时h、分m、秒s
now+1h当前时间加一小时,以毫秒为单位
now+1h+1m当前时间加一小时一分钟,以毫秒为各单位
now+1h/d当前时间加一小时,四舍五入到最近一天
2018-01-01||+1M/d 2018-01-01加一个月,向下舍入到最近一天

响应过滤
filter_path
选择返回字段,逗号分割,可以使用*
两个通配符**匹配不确定名称的字段
curl -XGET '127.0.0.1:9200/_search?pretty&filter_path=took,hits.hits._id,hits._score'
curl -XGET '127.0.0.1:9200/_search?pretty&filter_path=hits.hits._source&_source=title'
flat_settings紧凑参数,为true时更加紧凑

RESTful Web Service

POST => Create 新增一个没有ID的资源
GET => Read 取得一个资源
PUT => Update 更新一个资源,或新增一个含有ID的资源
DELETE => Delete 删除一个资源

增删改查

创建库
PUT secisland?pretty 或者PUT secisland
查询库状态
GET _cat/indices?v 或者GET _cat/indices
插入数据
PUT secisland/secilog/1/ {"computer":"secisland","message":"secisland is an security company"}
格式:_index/_type/_id/
修改数据
POST secisland/secilog/1/_update {"doc":{"computer":"secisland","message":"secisland is an security company!"}}
查询文档
GET secisland/secilog/1/
删除文档
DELETE secisland/secilog/1/
删除库
DELETE secisland/

索引

索引是具有相同结构的文档集合

索引管理

创建索引

创建索引的时候可以通过修改number_of_shards和number_of_replicas来设置分片和副本的数量。默认分片为5,副本为1,副本数可以设置为0
PUT secisland/
{"settings":{"index":{"number_of_shards":3,"number_of_replicas":2}}} 设置分片数为3,副本数为2
{"settings":{"number_of_shards":3,"number_of_replicas":0}} 简写
对副本数的修改可以使用update-index-settings API实现
PUT secisland/_settings/ {"number_of_replicas":2}

文档字段都要有数据类型,默认可以自动识别,也可以使用mappings参数显式映射
创建自定义类型
PUT secisland/
{"settings":{"number_of_shards":3,"number_of_replicas":2},"mappings":{"secilog":{"properties":{"logType":{"type":"string","index":"not_analyzed"}}}}} 创建一个名号secilog的类型,类型中有一个字段logType,字段类型为string,不分析

删除索引

DELETE secisland/
删除索引需要指定索引名、别名或者通配符
删除多个可用逗号分隔,使用_all或*删除全部索引
配置文件中设置action.destructive_requires_name为true可以禁止通配符或_all删除索引

获取索引

从一个或者多个索引中获取信息
GET secisland/
获取索引需要指定索引名称,别名或者通配符返回结果过滤:自定义返回结果的属性
GET */_settings,_mappings  仅获取_settings和_mappings属性

打开/关闭索引

半闭的索引只能显示索引元数据,不能进行数据读写操作
POST /索引名/_close   POST /索引名/_open
可以同时打开或关闭多个索引,全部使用_all或*,使用ignore_unavailable=true可以不显示异常
配置文件设置action.destructive_requires_name为true禁止使用通配符和_all
禁止使用关闭索引功能settingscluster.indices.close.enable为false
索引映射管理

增加映射

可以向索引添加文档类型type或者向文档类型type中添加字段field
PUT secisland/ {"mappings":{"log":{"properties":{"message":{"type":"string"}}}}}
新建索引并设置文档类型为log,其中包含字段message类型为string
添加新的文档类型user和字段name
PUT secisland/_mapping/user {"properties":{"name":{"type":"string"}}}
向已经存在的索引中log类型下添加新的字段user_name
PUT secisland/_mapping/log {"properties":{"user_name":{"type":"string"}}}

多个索引设置映射

一次向多个索引添加文档类型
PUT {index}/_mapping/{type} {body}
{index}可以使用逗号分割,支持通配符和*

更新字段映射

一般情况下,现在字段映射不会更新,但有些例外
新的属性被添加到对象数据类型的字段
新的多域字段被添加到现有字段
doc_values可以被禁用
增加ignore_above参数
eg:
PUT secisland/_mapping/user
{"mappings":{"user":{"properties":{"name":{"properties":{"first":{"type":"string"}}},"user_id":{"type":"string","index":"not_analyzed","ignore_above":100}}}}}
可以增加name的子字段,可以添加"ignore_above":100

不同类型这间的冲突

同一索引内,可以有多个类型,但是不同类型的同名字段映射是相同的,因为它们内部在同一领域内。更新时会抛出异常,除非在更新时指定update_all_types参数,此时将更所所有同名字段
{"mappings":{"type_one":{"properties":{"text":{"type":"string","analyzer":"standard"}}},"type_two":{"properties":{"text":{"type":"string","analyzer":"standard"}}}}}
要修改text字段,需要这样操作:
PUT secisland/_mapping/type_one?update_all_types
{"properties":{"text":{"type":"string","analyzer":"standard","search_analyzer":"whitespace"}}}

获取映射

允许通过索引或者索引和类型来搜索
GET secisland/_mapping/type_one
GET secisland/_mapping
系统支持同时获取多个索引和类型
{index}/_mapping/{type} {index}{type}均可用逗号分割,可使用通配符和_all
_all/_mapping和_mapping等价

获取字段映射

格式为:{index}/{type}/_mapping/field/{field} 倒数第二个field为固定关键字,{type}和_mapping可以互换位置
其中{index}{type}{field}可以逗号分割,通配符和_all
GET secisland/type_two/_mapping/field/text

判断类型是否存在
HEAD secisland/type_one 存在返回200,不存在返回404

索引别名

可以对别名编写过滤器或者路由,别名不能重复,也不能和索引名重复。别名类似于数据库中的视图

添加别名
POST _aliases {"actions":[{"add":{"index":"secisland","alias":"alias1"}}]}
删除别名
POST _aliases {"actions":[{"remove":{"index":"secisland","alias":"alias1"}}]}
别名没有修改的语法,只能先删除再增加,如
{"actions":[{"remove":{"index":"secisland","alias":"alias1"}},{"add":{"index":"secisland","alias":"new_alias"}}]}
同时设置多个索引的别名
POST _aliases {"actions":[{"add":{"indices":["secisland","logstash*"],"alias":"new_alias"}}]}
对某一别名做索引时,如果该别名关联多个索引会报错

过滤索引别名

使用查询DSL来定义适用于所有的搜索、计数、查询删除等
新建索引:
PUT test1 {"mappings":{"type1":{"properties":{"user":{"type":"string","index":"not_analyzed"}}}}}
创建过滤别名:
POST _aliases {"actions":[{"add":{"index":"test1","alias":"alias2","filter":{"term":{"user":"kimchy"}}}}]}
别名可以和路由关联,可以避免不必要的碎片操作,如
POST _aliases {"actions":[{"add":{"index":"test1","alias":"alias1","routing":"1"}}]}
同时指定搜索路由或者查询路由
POST _aliases {"actions":[{"add":{"index":"test1","alias":"alias3","routing":"1,2","index_routing":"2"}}]}
注意,搜索路由可以指定多个值,索引路由只能指定一个值。如果使用路由别名操作的同时还有路由参数,则结果为别名路由和路由参数的交集,如
GET alias2/_search?q=user:kimchy&routing=2,3

通过参数添加别名
语法:PUT /{index}/_alias/{name} {"routing":"1","filter"}
其中:
index 参照的索引,可以用*,_all,正则表达式或者以逗号分割的多个名称
name 别名的名称
routing 别名对应的路由
filter 指定别名的过滤条件
添加一个别名
PUT secisland/_alias/2013

新建一个索引
PUT secisland {"mappings":{"secilog":{"properties":{"user_id":{"type":"integer"}}}}}
指定别名
PUT secisland/_alias/user_12 {"routing":"12","filter":{"term":{"user_id":12}}}

建索引的同时指定别名
PUT secisland/ {"mappings":{"type":{"properties":{"year":{"type":"integer"}}}},"aliases":{"current_day":{},"2014":{"filter":{"term":{"year":2014}}}}}

删除别名

语法:DELETE {index}/_alias/{name}

查询现有别名

可通过索引或别名进行查询
语法:GET {index}/_alias/{alias}  ignore_unavailable设置为true将忽略不存在的索引
GET secisland/_alias/*
HEAD也可以检查别名是否存在
HEAD _alias/2013
HEAD secisland/_alias/*
索引配置

更新索引配置

/_settings 针对所有索引
{index}/_settings  针对特定的索引设置副本数
PUT secisland/_settings {"index":{"number_of_replicas":4}}更新分词器
创建索引后可以添加新的分析器,添加分析器之前必须先关闭索引,添加之后再打开索引
POST secisland/_close
PUT secisland/_settings {"analysis":{"analyzer":{"content":{"type":"custom","tokenizer":"whitespace"}}}}
POST secisland/_open

获取配置

GET secisland/_settings
GET secisland/_settings/name=index.number_*    只返回index.number_*的配置

索引分析

analysis将文本块分析成单个的term词
分析器analyzers是一个组合,包含:
1、字符过滤器character filter,可以去除HTML标签或者转换&为and
2、分词器tokenizer 进行分词
3、标记过滤器token filters 可以修改词,转换大小写,去掉无意义的词或者增加同义词等测试分析器
POST _analyze {"analyzer":"standard","text":"this is a test"}自定义分析器,使用keyword分词器,lowercase分词过滤,字符过滤使用html_strip
POST _analyze {"tokenizer":"keyword","token_filters":["lowercase"],"char_filters":["html_strip"],"text":"this is a <b>test</b>"}
如果想获取分析器的更多细节,设置explain为true,默认为false,这将输出分词器详情
{"tokenizer":"keyword","token_filters":["lowercase"],"char_filters":["html_strip"],"explain":true,"text":"This is a <b>test</b>"}

索引模板

创建索引模板
模板包括索引的参数设置settings和映射mapping,在创建新索引的时候指定模板名称就可以使用模板定义好的参数设置和映射
PUT _template/template_1 {"template":"te*","settings":{"number_of_shards":1},"mappings":{"type1":{"_source":{"enabled":false}}}}
配置名称可以使用*,模板定义中也可以包括别名的定义等属性删除索引模板
DELETE _template/template_1获取索引模板
GET _template/*
GET _template/template_1判断索引模板是否存在
HEAD _template/template_1多个模板匹配
如果同时匹配多个模板,最后会合并所有匹配模板的配置,如果配置重复,按照order进行匹配,order从0开始,先匹配数字小的,再匹配数字大的
如果有相同的属性配置,后匹配的会覆盖前配置的

复制配置

如果使用共享文件系统,复制配置用来选择索引数据保存在磁盘的位置,以及es应该如何在索引副本分片上重复操作
为充分利用index.data_path和index.shadow_replicas设置,让es使用相同的数据目录为多个实例服务,需要在配置文件中设置
node.add_id_to_custom_path为false
可以在配置文件中设置path.shared_data权限管理标明自定义索引的位置,以便应用正确的权限
path.shared_data:/opt/data
这意味着es可以读写path.shared_data中所有子目录中的文档
可以在自定义数据路径中创建索引,每个节点使用这个路径来存储数据
PUT secisland {"index":{"number_of_shards":1,"number_of_replicas":4,"data_path":"/opt/data/secisland","shadow_replicas":true}}
可以使用设置更新接口修改的设置列表:
index.data_path 字符型索引数据使用的路径,es默认附加节点序号到路径中,确保相同机器上的多重实例不会共享数据目录
index.shadow_replicas 布尔值,指示索引是否应该使用副本
index.shared_filesystem 布尔值,指示索引使用共享文件系统。如果index.shadow_replicas为true,默认为true,其他情况下默认为false
index.shared_filesystem.recover_on_any_node 布尔值,指示索引的主分片是否可以恢复到集群中的任何节点,默认为false

重建索引

重建索引最基本的功能是拷贝文件从一个索引到另一个索引
POST _reindex {"source":{"index":"secisland"},"dest":{"index":"new_secisland"}}  需要索引中有数据才会生成新索引
返回值说明{
"took": 139,#从开始到结束操作的毫秒数
"timed_out": false,
"total": 1,
"updated": 1,#成功更新的文档数
"created": 0,#成功创建的文档数
"batches": 1,#从重建索引拉回的滚动响应的数量
"version_conflicts": 0,#重建索引中版本冲突的数量
"noops": 0,
"retries": 0,
"throttled_millis": 0,
"requests_per_second": "unlimited",
"throttled_until_millis": 0,
"failures": [ ]#所有索引失败的数组,如非空,则请求将中止
}
基本不大可能产生冲突,可以在接口中增加乐观并发控制,将version_type设置为internal,这样任何具有相同类型和ID的文档将被重写
将version_type设置为external则会保护源索引版本,如果在目标索引中有比源旧的版本,会更新
设置op_type为create将导致在目标索引中仅创建丢失的文件,所有现有的文件将导致版本冲突
POST _reindex {"source":{"index":"logstash-open-2018.04.11"},"dest":{"index":"new_secisland","version_type":"internal"}}
正常情况下发生冲突会中止,使用"conflicts":"proceed"可以只讲行计算
可以通过向源添加一个类型或者增加一个查询来限制文档数量
只复制用户名为kimchy的文档
POST _reindex {"source":{"index":"secisland","type":"secilog","query":{"term":{"user":"kimchy"}}},"dest":{"index":"new_secisland"}}
也可以设置大小来限制处理文件数量"size":12
{"size":10000,"source":{"index":"secsland","sort":{"data":"desc"}},"dest":{"index":"new_secisland"}}  使用了排序
也支持使用脚本来修改文档,如
{"source":{"index":"secisland"},"dest"{"index":"new_secisland","version_type":"external"},"script":{"internal":"if (ctx._source.foo == 'bar'){ctx._source.remove('foo')}"}}
可以修改的元字段包括:_id,_type,_index,_version,_routing,_parent,_timestamp,_ttl_reindex可以设置文档路由,如
{"source":{"index":"source","query":{"match":{"company":"cat"}}},"dest":{"index":"dest","routing":"=cat"}}
#复制所有文件从源索引为company等于cat的查询中复制到目标索引,目标索引的路由设置为cat默认_reindex每次处理大小为100,可以在源参数中用size参数进行修改
{"source":{"index":"source","size":1500},"dest":{"index":"dest"}}URL参数
_reindex接口可以接收pretty/refresh/wait_for_completion/consistency/timeout参数
refresh参数会导致所有写入请求的索引被刷新。与索引接口中的refresh不同,只有接收到数据的分片会进行刷新
如果请求中包含wait_for_completion=false,es将进行执行前检查后启动请求,然后返回一个task,可用于取消或得到任务状态
consistency控制每次写请求必须多少份分片响应
timeout控制每个写请求等待的分片时间任务查看
GET _task/?pretty&detailed=true&actions=*reindex
索引监控

包括索引的统计信息、碎片信息、恢复状态、分片信息

索引统计

提供索引中不同内容的统计数据,其中大多数统计数据也可以从节点级别范围取得
获取所有聚合以及索引的统计数据
GET _stats
GET /secisland/_stats
默认返回所有信息,也可以指定返回特定数据,选项有:

一些统计数据可以作用在字段粒度上,接受逗号分隔的字段列表
fields 包含统计数据中的字段列表,默认列表
completion_fields 包含完成建议统计数据中的字段列表
fielddata_fields 包含在字段数据统计数据中的字段列表
如:
#获取所有索引的混合和刷新统计数据
GET _stats/merge,refresh
#获取名为secisland索引中类型为type1和type2的文档统计数据
GET secisland/_stats/indexing?types=type1,type2
#获取分组group1和group2的搜索统计数据
GET _stats/search?groups=group1,group2返回的统计数据在索引级别发生聚合,生成名为primaries和total的聚合,其中primaries仅包含主分片的值,total是主分片和从分片的累计值
为了获取分片级别的统计数据,需要设置level参数为shards
当分片在集群中移动的时候,它们的统计数据会被清除,视作它在其他节点中被创建
即使分片“离开”一个节点,那个节点仍然会保存分片之前的统计数据

索引分片

提供lucene索引所在的分片信息。用来提供分片和索引的更多统计信息,可能是优化信息,删除的'垃圾'数据等
GET /secisland/_segments
GET /secisland,secisland2/_segments
GET _segments

索引恢复

提供正在进行恢复的索引分片信息,可以报告指定索引或者集群范围的恢复状态
GET secisland,secisland2/_recovery
GET _recovery?pretty&human
选项列表
detailed 显示详细的视图。主要用来查看物理索引文件的恢复,默认为false
active_only 显示正在进行的恢复,默认为false

索引分片存储

提供索引分片副本的存储信息。报告分片副本存在的节点、分片副本版本、指示分片副本最近的状态以及在开启分片索引时遭遇的任何异常
GET /secisland/_shard_stores
GET /secisland,secisland2/_shard_stores
GET /_shard_stores
列出存储信息的分片范围可以通过status参数进行修改。默认是yellow和red,使用green列出所有信息
GET _shard_stores?status=green
状态管理

包括清除索引缓存、索引刷新、冲洗索引、合并索引接口等

清除缓存

清除所有缓存或者关联一个或者更多索引的特定缓存
POST secisland/_cache/clear
明确清理所有缓存,可以明确设置query、fielddata和request来清理特定缓存

索引刷新

明确的刷新一个或多个索引,使之前最后一次刷新之后的所有操作被执行
POST secisland/_refresh
POST secisland,test/_refresh

冲洗

通过执行冲洗将数据保存到索引存储并且清除内部事务日志,以此来释放索引的内存空间
es通过使用内存启发式算发来自动触发冲洗操作
POST secisland/_flush

合并索引

强制合并一个或更多索引。合并分片数量和每个分片保存的lucene索引,强制合并可以通过合并来减少分片数量
调用会被阻塞直到合并完成,如果http连接丢失,请求会在后台继续执行,任何新的请求都会被阻塞直到前一个强制合并完成
POST secisland/_forcemerge
POST secisland/_forcemerge?max_num_segments=1
参数:
max_num_segments 用于合并的分片数量,为充分合并,设置它的值为1
only_expunge_deletes 合并过程是否只删除分片中被删除的文档。lucene中,文档不会从分片中删除,只是标记为删除,通过执行合并,可以删除这些标记为删除的文档,默认值为false
flush 强制合并之后是否执行冲洗,默认为true
文档管理

增加文档

如果有相同id的文档,则更新此文档
PUT secisland/secilog/1
{"collect_type":"syslog","collect_date":"2016-01-11T09:32:12","message":"Failed to login"}
返回:
{"_index":"secisland","_type":"secilog","_id":"1","_version":2,"_shards":{"total":2,"successful":1,"failed":0},"created":false}
其中total表示文档被创建的时候,在多少分片中进行操作,包括主分片和副本分片,所以这里为2,因为包括一个副本分片

1、自动创建索引
创建文档的时候,如果索引不存在,会自动创建索引。自动创建的索引会自动映射每个字段的类型
可以在配置文件中设置action.auto_create_index为false禁用自动创建索引
自动创建索引可以通过模板设置索引名称,如可以设置action.auto_create_index为+aaa* -bbb* +ccc* -*  (+为准许,-为禁止)

2、版本号
每个文档都有一个版本号_version,通过版本号可以达到并发控制的效果,在操作文档的过程中指定版本号,哪果和版本号不一致时操作会被拒绝
版本号常用在对事务的处理中
PUT secisland/secilog/1?version=4 {"message":"Failed to loginSSSS"} 当指定的版本号不是最新的时,会更新失败
版本号是实时更新的,不存在缓存现象,操作时不指定版本号,则系统不对版本号进行一致性检查
版本号可以从外部获取,当使用外部版本号时,操作文档时会对比参数中版本号是否大于文档中版本号,只有大于时才执行操作

3、操作类型
通过op_type=create参数强制执行创建操作,只有在系统中不存在此文档的时候才会创建成功,不存在更新行为
PUT secisland/secilog/1?op_type=create {"message":"Failed to loginSSMSS"}
另一个写法是
PUT secisland/secilog/1/_create {"message":"Failed to loginSSMSS"}

4、自动创建ID
当创建文档时,不指定ID,系统会自动创建ID。自动生成的ID是一个20位随机数
POST secisland/secilog/?op_type=create {"message":"Failed to loginSSMSS"}
POST secisland/secilog/ {"message":"Failed to loginSSMSS"}

5、分片选择
默认分片的选择是通过id的散列值进行控制
可以使用router来使用指定参数的哈希而不是id的哈希
POST secisland/secilog/?routing=lily {"message":"Failed to loginSSMSS"}

6、其它说明
分布式 索引操作只针对主节点的分片进行,再分发到副本分片中
一致性 为防止当网络出现问题时写入不一致,只有在有效节点数量大于一定数量时生效[总结点数/2+1],该值可以通过action.write_consistency参数设置
刷新 更新的时候可以指定refresh为true立即刷新,系统做了充分的优化,不会对系统产生任何影响,需要注意的是查询操作refresh操作没有意义
空操作 当文档内容没有任何改变时,更新操作也会生效,仅体现为版本号的变化,可以指定detect_noop为true解决该问题,该参数在创建索引的时候无效
超时 默认为1分钟,可以通过设置timeout修改,如timeout=5m

更新删除文档

可以通过脚本操作来更新文档。更新操作从索引中获取文档,再执行脚本,最后获得返回结果。它使用版本号控制文档获取或者重建索引
更新操作是完全重新索引文件
PUT secisland/secilog/1 {"counter":1,"tags":["red"]}1、脚本开启功能
基于安全考虑,默认是禁用动态脚本的。如果需要开启,在配置文件中添加以下代码:
script.inline: on
script.indexed: on
script.file: on
配置后需要重启es2、用脚本更新文档
POST secisland/secilog/1/_update
{"script":{"inline":"ctx._source.counter += count","params":{"count":4}}}
POST secisland/secilog/1/_update
{"script":{"inline":"ctx._source.tags += tag","params":{"tag":"blue"}}}
在脚本中,除了_source外,其它内置参数也可以使用,如_index、_type、_version、_routing、_parent、_timestamp、_ttl等
POST secisland/secilog/1/_update {"script":"ctx._source.name_of_new_field = \"value_of_new_field\""}  #添加新字段
POST secisland/secilog/1/_update {"script":"ctx._source.remove(\"name_of_new_field\")"}  #删除一个字段
#条件判断,删除tags字段包含blue的文档
{"script":{"inline":"ctx._source.tags.contains(tag) ? ctx.op=\"delete\" : ctx.op=\"none\"","params":{"tag":"blue"}}}
部分文档更新:
将文档合并到现有文档中,简单的递归合并、对象内部合并、替换核心的键值和数组
POST secisland/secilog/1/_update {"doc":{"name":"new_name"}}  #新增字段name
当新文档和老文档不一致时,会重新建立索引,可以通过detect_noop为false设置为任何时候都重新建立索引
POST secisland/secilog/1/ {"doc":{"name":"new_name"},"detect_noop":false}删除文档
DELETE secisland/secilog/1/

查询文档

通过文档ID查询具体的某一个文档
GET secisland/secilog/1/
GET secisland/_all/1/     #type字段可以设置为_all
默认的,查询获得的数据是实时的,且不受索引刷新率影响。禁用实时性,可以将参数realtime设置为false,或者全局设置action.get.realtime为false
GET secisland/secilog/1?_source=false  #不返回_source字段
#过滤_source中的部分字段
当需要返回多个字段时,可以使用逗号或者*
GET secisland/secilog/1?_source_include=doc
GET secisland/secilog/1?_source_exclude=doc使用fields字段,可以查询一组字段,返回字段是数组类型的
GET secisland/secilog/1?fields=year,sex
如果建立索引后还没来得及刷新,查询得到的内容是事务的日志
但有些字段只有在索引的时候才会产生,当访问时,会抛出异常,可以通过设置ignore_errors_on_generated_fields=true来忽略异常1、只获取文档内容
{index}/{type}/{id}/_source
GET secisland/secilog/1/_source

2、分片选择
在查询的时候指定路由routing,当路由不存在时,返回空值
GET secisland/secilog/1?routing=secisland

3、查询参数
通过参数,可以指定查询在主节点上还是副本节点上执行
_primary 在主节点上
_local 尽可能在本地节点上进行
refresh 可设置为true,使之在搜索操作前刷新相关分片保证可以及时查询到,但会消耗系统资源,如非必要勿开启

多文档操作

多文档查询bulk
1、多文档查询
可以分别指定index、type、id来进行多个文档的查询。返回查询到的文档数组
POST _mget
{"docs":[{"_index":"secisland","_type":"secilog","_id":"1"},{"_index":"secisland","_type":"secilog","_id":"2"}]}
在查询的时候,index、type可以在URL中直接写
POST secisland/secilog/_mget {"docs":[{"_id":"1"},{"_id":"2"}]}
POST secisland/secilog/_mget {"ids":["1","2"]}

2、type参数说明
_type允许为空,当设置为空或者_all的时候,系统会匹配第一个查询到的结果
如果不设置_type,当有许多文件有相同的_id的时候,系统最终得到的只有第一个匹配的文档
默认,_source字段将在每个文档中返回,可以使用_source、_source_include、_source_exclude进行过滤
POST secisland/secilog/_mget
{"docs":[{"_id":"1","_source":false},{"_id":"2","_source":["collect_type","collect_date"]}]}

3、块操作
可以在一个接口中处理文档内容,包括创建、删除和修改,块操作可以提高系统效率【?】
POST _bulk
{"index":{"_index":"secisland","_type":"secilog","_id":"10"}}
{"field1":"value1"}
{"index":{"_index":"secisland","_type":"secilog","_id":"13"}}
{"field1":"value3"}
{"delete":{"_index":"secisland","_type":"secilog","_id":"12"}}
和批量查询类似,_bulk、{index}/_bulk、{index}/{type}/_bulk三种方式都可以执行

4、索引词频率
term vector是lucene中的概念,就是对于文档中的某一列,如title、body这种文本类型的建立词频的多维向量空间,每一个词就是一个维度,这个维度的值就是这个词在这个列中的频率
es中termvectors返回在索引中特定文档的统计信息,是实时分析的,如果不想实时分析,可以设置realtime参数为false
默认情况下,索引词频率统计是关闭的,需要在建立索引的时候手工打开
#建一个打开了索引词统计的索引
PUT secisland
{"mappings":{"secilog":{"properties":{"type":{"type":"string","term_vector":"with_positions_offsets_payloads","store":true,"analyzer":"fulltext_analyzer"},"message":{"type":"string","term_vector":"with_positions_offsets_payloads","analyzer":"fulltext_analyzer"}}}},"settings":{"index":{"number_of_shards":1,"number_of_replicas":0},"analysis":{"analyzer":{"fulltext_analyzer":{"type":"custom","tokenizer":"whitespace","filter":["lowercase","type_as_payload"]}}}}}
#插入两条数据
PUT secisland/secilog/1 {"type":"syslog","message":"secilog test test test "}
PUT secisland/secilog/2 {"type":"file","message":"Another secilog test"}
#用_termvectors查询统计结果
GET secisland/secilog/1/_termvectors
#对于索引词统计,还可以指定参数查询
POST secisland/secilog/1/_termvectors
{"fields":["message"],"offsets":true,"payloads":true,"positions":true,"term_statistics":true,"field_statistics":true}

查询更新接口

在索引中更新每一个文档,而文档内容并没有改变的情况下使用,在增加新的属性或者修改映射的时候非常有用
POST secisland/_update_by_query?conflicts=proceed
POST secisland/_update_by_query?conflicts=proceed {"query":{"term":{"user":"kimchy"}}}
支持脚本对文档内容的更新,如
POST secisland/_update_by_query {"script":{"inline":"ctx._source.likes++"},"query":{"term":{"user":"kimchy"}}}
默认_update_by_query采用滚动100批次,可以在URL中用scroll_size来改变批次的大小
POST secisland/_update_by_query?scroll_size=1000
另外,还支持refresh、wait_for_completion、consistency、timeout参数

当创建一个没有动态映射的索引,如果有新的数据内容,系统会添加新的映射值来匹配数据中的多个字段
PUT secisland/ {"mappings":{"secilog":{"dynamic":false,"properties":{"text":{"type":"string"}}}}}
插入数据
POST secisland/secilog {"text":"words words","flag":"bar"}
添加映射
PUT secisland/_mapping/secilog {"properties":{"text":{"type":"string"},"flag":{"type":"string","analyzer":"keyword"}}}
但是这个时候查询数据,不会找到任何值
POST secisland/_search?filter_path+hits.total {"query":{"match":{"flag":"bar"}}}
这时可以用更新的查询请求来获得数据
先执行请求:POST secisland/_update_by_query?refresh&conflicts=proceed  #conflicts=proceed发生冲突时只进行简单计数,不中止
现在就可以查询了

 

 

 

 

 

 

 

 

 

 

转载请注明:轻风博客 » elasticsearch技术解析与实战(一) 入门和索引

喜欢 (0)or分享 (0)