MyBlog


ES总结三:索引管理

<p>[TOC]</p> <h1>索引管理</h1> <h2>新建索引</h2> <p>创建索引和在MySQL中创建一个数据库是一样的,注意Elasticsearch索引名称中不能出现大写字母。例如新建一个索引,名为blog <code>PUT blog</code> 响应结果: <code>"acknowledged":true,</code> <code>"shardsacknowledged":true</code> Elasticsearch默认给一个索引设置5个分片1个副本,一个索引的分片数一经指定后就不能再修改,副本数可以通过命令随时修改。 如果想创建自定义分片数和副本数的索引,可以通过setting参数在索引时设置初始化信息。以创建3个分片0个副本名为blog的索引为例,命令如下: <code>put blog</code> <code>"settings":{"number_of_shards":3,_number_of_replicas":0}</code></p> <h2>更新副本数量:</h2> <p>Elasticsearch支持修改一个已存在索引的副本数,把blog索引的副本数设置为2,命令如下: <code>PUTblog/_settings</code> <code>{"number_of_replicas":2}</code></p> <h2>读写权限</h2> <p>除了设置分片和副本,还可以对索引的读写操作进行限制,下面是三个读写权限的参数: •blocks.read<em>only:true 设置当前索引只允许读不允许写或者更新。 •blocks.read:true 禁止对当前索引进行读操作。 •blocks.write:true 禁止对当前索引进行写操作。 以禁止blog索引进行写操作为例,执行命令如下: `PUTblog/settings</em> {&quot;blockswrite&quot;:true}`</p> <h2>查看索引信息</h2> <p>使用GET方法加insetting参数可以查看一个索引的所有配置信息 <code>GET blog/_settings</code> 返回值如下:</p> <pre><code class="language-json">{ "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" } } } } }</code></pre> <p>同时查看多个索引的setting信息,命令如下: <code>GET blog,twitter/_settings</code> 查看集群中所有索引的setting信息,命令如下: <code>GET all/_settings</code></p> <h1>删除索引</h1> <p>删除名为blog的索引,命令如下: delete blog</p> <h1>索引别名</h1> <p>索引别名就是给一个索引或者多个索引起的另一个名字。为名为test1的索引创建别名alias1,命令格式如下: <code>POST /_aliases</code></p> <pre><code class="language-json">{ "actions": [{ "add": { "index": "test1", "alias": "alias1" } }] }</code></pre> <p>移除别名 <code>POST /_aliases</code></p> <pre><code class="language-json">{ "actions": [{ "remove": { "index": "test1", "alias": "alias1" } }] }</code></pre> <p>给多个索引创建别名 <code>POST /_aliases</code></p> <pre><code class="language-json">{ "actions": [{ "add": { "index": "test1", "alias": "alias1" }; "add": { "index": "test2", "alias": "alias1" } }] }</code></pre> <p>一次性移除别名 <code>POST /_aliases</code></p> <pre><code class="language-json">{ "actions": [{ "remove": { "index": ["test1","test2"], "alias": "alias1" } }] }</code></pre> <p>查看索引的别名 <code>GET/test/_aliases</code> 查看索引可用别名 <code>GET/_aliases</code></p> <h1>文档管理</h1> <h2>新建文档:</h2> <p><code>PUT blog/article</code> 文章内容为JSON形式,</p> <h2>获取文档</h2> <p><code>GET blog/article/{docid}</code></p> <h2>更新文档</h2> <p>文档被索引之后,如果要更新,那么Elasticsearch内部首先要找到这个文档,删除旧的文档内容执行更新,更新完后再索引最新的文档</p> <h2>删除文档</h2> <p><code>DELETEblog/article/{docID}</code></p> <h1>路由机制</h1> <p>Elasticsearch是一个分布式系统,当索引一个文档时文档会被存储到master节点上的一个主分片上。那么Elasticsearch是如何知道文档属于哪个分片的呢?再有当你创建一个新文档,Elasticsearch是如何知道应该存储在分片1还是分片2上?要想回答这些问题,就需要了解Elasticsearch的路由机制。Elasticsearch的路由机制即是通过哈希算法,将具有相同哈希值的文档放置到同一个主分片中,分片位置计算方法: <code>shard=hash(routing)%number_of_primary_shards</code> routing值可以是一个任意字符串,<strong>Elasticsearch默认将文档的id值作为routing值</strong>,通过哈希函数根据routing字符串生成一个数字,然后除以主切片的数量得到一个余数remainder),余数的范围永远是0到number_of_primary_shards-1,这个数字就是特定文档所在的分片。这种算法基本上会保持所有数据在所有分片上的一个平均分布,而不会造成数据分配不均衡的情况. 也可以自定义routing值。默认的路由模式可以保证数据平均分布,文档分配算法对我们来说是透明的,很多时候性能也不是问题。自定义routing值在深入理解数据特征之后,能够带来很多使用上的方便和性能上的提升 假设存在一个有50个分片的索引,在集群上执行一次查询的过程如下: (1)查询请求首先被集群中的一个节点接收。 (2)接收到这个请求的节点,将这个查询广播到这个索引的每个分片上。 (3)每个分片执行完搜索查询并返回结果。 (4)结果在通道节点上合并、排序并返回给用户 默认情况下,Elasticsearch使用文档的id将文档平均分布于所有的分片上,这导致了Elasticsearch不能确定文档的位置,所以它必须将这个请求广播到所有的50个分片上去执行。<strong>主分片的数量在索引创建的时候是固定的,并且永远不能改变。因为如果分片的数量改变了,所有先前的路由值就会变成非法,文档相当于丢失了</strong>。使用自定义的路由模式,可以使查询更具目的性。你不必盲目地去广播查询请求,而是要告诉Elasticsearch你的数据在哪个分片上.</p> <h1>映射管理</h1> <p>映射也就是Mapping用来定义一个文档以及其所包含的字段如何被存储和索引,可以在映射中事先定义字段的数据类型、分词器等属性。Elasticsearch创建索引时同样可以设置字段的属性,作用是使索引的配置更加灵活和完善,可以在Mapping中设置字段的类型、字段的权重等信息。</p> <h2>静态映射</h2> <p>类似于数据库的建表语句DDL等,相比动态映射,通过静态映射可以添加更详细、更精准的配置信息</p> <h2>动态映射</h2> <p>动态映射是一种偷懒的方式,可直接创建索引并写入文档,文档中字段的类型是Elasticsearch自动识别的,不需要在创建索引的时候设置字段的类型。在实际项目中,如果遇到的业务在导入数据之前不确定有哪些字段,也不清楚字段的类型是什么,使用动态映射非常合适。 <img src="https://www.showdoc.cc/server/api/common/visitfile/sign/5ccec99e04d4a592c3089c47b073da2a?showdoc=.jpg" alt="" /> 日期检测 当Elasticsearch碰到一个新的字符串类型的字段时,它会检查这个字符串是否包含一个可识别的日期,比如2014-01-01。如果看起来像日期,那么它会被识别为一个date类型的字段,否则会将它作为string字段进行添加。这种自动检测机制有时会导致一些问题,假设一种情况,比如索引一份这样的文档到Elasticsearch中 <code>{"note":"2014-01-01"}</code> 如果note字段第一次被发现,那么根据规则它会被作为date字段添加。但是如果下一份文档是这样的: <code>{"note":"Logged out"}</code> 这时该字段显然不是日期类型,但是已经太迟了。该字段的类型已经是日期类型的字段了,因此这会导致一个异常被抛出。可以通过在根对象上将date_detecti0n设置为false来关闭日期检测。 <code>"date_detection":false</code> 有了以上的映射,一个字符串总是会被当作string类型。如果需要新增一个date类型的字段,需要手动添加。</p>

页面列表

ITEM_HTML