之前写了一篇Elasticsearch学习整理的文章,介绍了elasticsearch的一些基本概念以及REST API
的相关用法,现在对elasticsearch索引的相关知识做一些补充。
- 倒排索引
- 索引初始化
- 索引的CURD操作
- Mapping映射
- 索引模板
- 版本控制
倒排索引
常规索引建立方式:
文档–>关键词的映射过程(正向索引) 缺点:费时,需要把文档全部遍历一遍
倒排反向建立索引:
关键词–>文档的映射 把正向索引的结果重新构造成倒排索引(反向索引)
索引初始化
两个最重要的设置:
number_of_shards #定义一个索引的主分片个数,默认值是 `5`。这个配置在索引创建后不能修改。
number_of_replicas #每个主分片的复制分片个数,默认是 `1`。这个配置可以随时在活跃的索引上修改。
Elasticsearch 提供了优化好的默认配置。除非你明白这些配置的行为和为什么要这么做,请不要修改这些配置。
例如创建一个只有一个主分片,没有复制分片的索引:
PUT /my_temp_index
{
"settings": {
"number_of_shards" : 1,
"number_of_replicas" : 0
}
}
或者:
curl -H "Content-Type: application/json" -XPUT 192.168.20.60:9200/my_index?pretty -d '
{
"settings": {
"number_of_shards": 1,
"number_of_replicas": 0
}
}'
然后,利用update-index-settings API 动态修改复制分片个数
PUT /my_index/_settings
{
"number_of_replicas" : 1
}
GET /library/_settings #_settings参数查看该索引详细配置信息
GET /_all/_settings #获取所有索引信息,如果查看多个需要索引信息需要使用","分隔
索引的CURD操作
创建索引
# /索引名称/Type名称/文档ID
PUT /library/books/1
{
"title": "111",
"name": {
"first": "name1",
"last": "111"
},
"publish_data": "2018-05",
"price": "49.99"
}
可以不指定ID,需要使用POST 自动生成ID:
POST /library/books/
{
"title": "222",
"name": {
"first": "name2",
"last": "222"
},
"publish_data": "2018-05",
"price": "31"
}
查看索引
GET /library/books/1 #通过ID获取文档信息
GET /library/books/1?_source=title,price #通过_source获取指定的字段
更新索引
更新同一ID下的文档,可以通过覆盖的方式更新
PUT /library/books/1
{
"title": "111",
"name": {
"first": "name1",
"last": "111"
},
"publish_data": "2018-05",
"price": "59.99"
}
或者通过_update API
的方式单独更新你想要更新的字段(POST
)
POST /library/books/1/_update
{
"doc": {
"price": "10"
}
}
删除索引
DELETE /library/books/1
DELETE /library
Mapping映射
映射:定义如何存储和索引文档及其所包含的字段的过程
分类:静态映射和动态映射
动态映射:文档中碰到一个以前没见过的字段时,动态映射可以自动决定该字段的类型,并对该字段添加映射
配置:通过dynamic
属性进行控制,适用在根对象上或者object类型的任意字段上
- true:默认值,动态添加字段;
- false:忽略新字段
- strict:碰到陌生字段,抛出异常
管理映射:
GET /library/_mapping #获取某个索引的映射信息
GET /library/_mapping/books #获取某个索引下某一type的映射信息
更新修改mapping映射:
mapping一旦建立,就不能更改现有的字段映射,如果要推倒现有的映射,需要重新建立一个索引,然后重新定义映射然后把之前索引里的数据导入到新建的索引里。
实现方法:
1.给现有的索引定义一个别名,并且把现有的索引指向这个别名。运行:
PUT /现有索引/_alias/别名索引
2.新创建一个索引,定义好最新的映射
3.将别名指向新的索引,并且取消之前索引的指向。运行:
POST /_aliases
{
"actions": [
{
"remove": {
"index": "现有索引名",
"alias": "别名A"
}
}
{
"add": {
"index": "新建索引名",
"alias": "别名A"
}
}
]
}
以上步骤可以实现索引的平滑过渡,并且是零停机的。
索引模板
在logstash与elasticsearch集成的时候,总共有如下几种使用模板的方式:
- 使用默认自带的索引模板 ,大部分的字段都会分词,适合开发和时候快速验证使用
- 在logstash收集端自定义配置模板,因为分散在收集机器上,维护比较麻烦
- 在elasticsearc服务端自定义配置模板,由elasticsearch负责加载模板,可动态更改,全局生效,维护比较容易
第三种需要在elasticsearch的集群中的config/templates路径下配置模板json,在elasticsearch中索引模板可分为两种:
- 静态模板:适合索引字段数据固定的场景,一旦配置完成,不能向里面加入多余的字段,否则会报错
- 动态模板:适合字段数不明确,大量字段的配置类型相同的场景,多加字段不会报错 ,如果添加的字段非常多,有可能造成es集群宕机
参考链接:http://qindongliang.iteye.com/blog/2290384
版本控制
数据在多线程操作下的准确性
悲观锁:假定会发生冲突,屏蔽一切有可能违反数据完整性的操作
乐观锁:假设不会发生冲突,只在提交操作时检查是否违反数据完整性
内部版本控制:_version自增长,修改数据后,_version会自动加1
判断提供的version值是否等于当前version值,如果不一致会失败
外部版本控制:为了保证_version与外部版本控制的数值一致,使用version_type=external
检查数据当前的version值是否小于请求中的version值。
检查数据当前的version值是否小于请求的version值(提供的值必须大于当前version值才会成功,version值为整数)
说明:当我们索引一个新文档时,”_version”的值为1,使用update更新该文档后”_version”的值自动增长为2,此时执行
POST /library/books/6/_update?version=3
{
"doc": {"price":16}
}
因为指定了”version=3”与当前版本(2)不一致,就会报版本冲突的错误。
使用外部版本控制机制,需要指定version_type=external
,如(version_type=external不支持update API)
PUT /library/books/6?version=5&version_type=external
{
"title": "es6",
"price": 26
}
当前版本直接从2变成了5,依据是判断检查数据当前的version值是否小于请求中的version值,满足条件就能执行成功。