ES总结三:索引管理

索引管理

新建索引

创建索引和在MySQL中创建一个数据库是一样的,注意Elasticsearch索引名称中不能出现大写字母。例如新建一个索引,名为blog
PUT blog
响应结果:
"acknowledged":true,
"shardsacknowledged":true
Elasticsearch默认给一个索引设置5个分片1个副本,一个索引的分片数一经指定后就不能再修改,副本数可以通过命令随时修改。
如果想创建自定义分片数和副本数的索引,可以通过setting参数在索引时设置初始化信息。以创建3个分片0个副本名为blog的索引为例,命令如下:
put blog
"settings":{"number_of_shards":3,_number_of_replicas":0}

更新副本数量:

Elasticsearch支持修改一个已存在索引的副本数,把blog索引的副本数设置为2,命令如下:
PUTblog/_settings
{"number_of_replicas":2}

读写权限

除了设置分片和副本,还可以对索引的读写操作进行限制,下面是三个读写权限的参数:
•blocks.readonly:true 设置当前索引只允许读不允许写或者更新。
•blocks.read:true 禁止对当前索引进行读操作。
•blocks.write:true 禁止对当前索引进行写操作。
以禁止blog索引进行写操作为例,执行命令如下:
`PUTblog/settings
{“blockswrite”:true}`

查看索引信息

使用GET方法加insetting参数可以查看一个索引的所有配置信息
GET blog/_settings
返回值如下:

{
    "blog": {
        "settings ": {
            "index ": {
                "number_of— shards ": "3 ",
                "blocks": {
                    "write": "false"
                }
                "provided一name ": "blog ",
                "creation_date ": "1503133584844 ",
                "number_of_replicas ": "2 ",
                "uuid ": "0yQX5PqNTtKmwRQouFsd8QM,
                "version": {
                    "created": "5040099"
                }
            }
        }
    }
}

同时查看多个索引的setting信息,命令如下:
GET blog,twitter/_settings
查看集群中所有索引的setting信息,命令如下:
GET all/_settings

删除索引

删除名为blog的索引,命令如下:
delete blog

索引别名

索引别名就是给一个索引或者多个索引起的另一个名字。为名为test1的索引创建别名alias1,命令格式如下:
POST /_aliases

{
    "actions": [{
        "add": {
            "index": "test1",
            "alias": "alias1"
        }
    }]
}

移除别名
POST /_aliases

{
    "actions": [{
        "remove": {
            "index": "test1",
            "alias": "alias1"
        }
    }]
}

给多个索引创建别名
POST /_aliases

{
    "actions": [{
        "add": {
            "index": "test1",
            "alias": "alias1"
        };
        "add": {
            "index": "test2",
            "alias": "alias1"
        }
    }]
}

一次性移除别名
POST /_aliases

{
    "actions": [{
        "remove": {
            "index": ["test1","test2"],
            "alias": "alias1"
        }
    }]
}

查看索引的别名
GET/test/_aliases
查看索引可用别名
GET/_aliases

文档管理

新建文档:

PUT blog/article
文章内容为JSON形式,

获取文档

GET blog/article/{docid}

更新文档

文档被索引之后,如果要更新,那么Elasticsearch内部首先要找到这个文档,删除旧的文档内容执行更新,更新完后再索引最新的文档

删除文档

DELETEblog/article/{docID}

路由机制

Elasticsearch是一个分布式系统,当索引一个文档时文档会被存储到master节点上的一个主分片上。那么Elasticsearch是如何知道文档属于哪个分片的呢?再有当你创建一个新文档,Elasticsearch是如何知道应该存储在分片1还是分片2上?要想回答这些问题,就需要了解Elasticsearch的路由机制。Elasticsearch的路由机制即是通过哈希算法,将具有相同哈希值的文档放置到同一个主分片中,分片位置计算方法:
shard=hash(routing)%number_of_primary_shards
routing值可以是一个任意字符串,Elasticsearch默认将文档的id值作为routing值,通过哈希函数根据routing字符串生成一个数字,然后除以主切片的数量得到一个余数remainder),余数的范围永远是0到number_of_primary_shards-1,这个数字就是特定文档所在的分片。这种算法基本上会保持所有数据在所有分片上的一个平均分布,而不会造成数据分配不均衡的情况.
也可以自定义routing值。默认的路由模式可以保证数据平均分布,文档分配算法对我们来说是透明的,很多时候性能也不是问题。自定义routing值在深入理解数据特征之后,能够带来很多使用上的方便和性能上的提升
假设存在一个有50个分片的索引,在集群上执行一次查询的过程如下:
(1)查询请求首先被集群中的一个节点接收。
(2)接收到这个请求的节点,将这个查询广播到这个索引的每个分片上。
(3)每个分片执行完搜索查询并返回结果。
(4)结果在通道节点上合并、排序并返回给用户
默认情况下,Elasticsearch使用文档的id将文档平均分布于所有的分片上,这导致了Elasticsearch不能确定文档的位置,所以它必须将这个请求广播到所有的50个分片上去执行。主分片的数量在索引创建的时候是固定的,并且永远不能改变。因为如果分片的数量改变了,所有先前的路由值就会变成非法,文档相当于丢失了。使用自定义的路由模式,可以使查询更具目的性。你不必盲目地去广播查询请求,而是要告诉Elasticsearch你的数据在哪个分片上.

映射管理

映射也就是Mapping用来定义一个文档以及其所包含的字段如何被存储和索引,可以在映射中事先定义字段的数据类型、分词器等属性。Elasticsearch创建索引时同样可以设置字段的属性,作用是使索引的配置更加灵活和完善,可以在Mapping中设置字段的类型、字段的权重等信息。

静态映射

类似于数据库的建表语句DDL等,相比动态映射,通过静态映射可以添加更详细、更精准的配置信息

动态映射

动态映射是一种偷懒的方式,可直接创建索引并写入文档,文档中字段的类型是Elasticsearch自动识别的,不需要在创建索引的时候设置字段的类型。在实际项目中,如果遇到的业务在导入数据之前不确定有哪些字段,也不清楚字段的类型是什么,使用动态映射非常合适。

日期检测
当Elasticsearch碰到一个新的字符串类型的字段时,它会检查这个字符串是否包含一个可识别的日期,比如2014-01-01。如果看起来像日期,那么它会被识别为一个date类型的字段,否则会将它作为string字段进行添加。这种自动检测机制有时会导致一些问题,假设一种情况,比如索引一份这样的文档到Elasticsearch中
{"note":"2014-01-01"}
如果note字段第一次被发现,那么根据规则它会被作为date字段添加。但是如果下一份文档是这样的:
{"note":"Logged out"}
这时该字段显然不是日期类型,但是已经太迟了。该字段的类型已经是日期类型的字段了,因此这会导致一个异常被抛出。可以通过在根对象上将date_detecti0n设置为false来关闭日期检测。
"date_detection":false
有了以上的映射,一个字符串总是会被当作string类型。如果需要新增一个date类型的字段,需要手动添加。