elasticsearch 索引详解

r囧r小猫 2024-03-16 10:27 87阅读 0赞

索引

此文章已收录至项目 Developer-Knowledge-Base

我找到的最新的官方文档(英文):链接

索引类似于 MySQL 中的表,

创建索引

基本使用

语法:PUT /<index>

index 就是索引名,,对于索引名,有以下限制

  • 只能使用小写字母
  • 不能使用这些字符 \/*?"<>|,#``
  • 不能以 - + _ 开头
  • 长度不能超过 255 个字节
  • 冒号 :7.0 版本之前可以使用,7.0 版本之后就不能使用了

请求体

请求体内支持这些参数

aliases:(可选)索引别名,类似与 MySQL 中的视图,将单独一章来写别名

mappings:(可选)映射对象,就相当于 MySQL 中的定义表结构,索引中字段的映射。此映射可以包括:

  • 字段名称
  • 字段数据类型]
  • 映射参数

settings:可选,索引设置)配置 索引的选项。

mappings (索引映射)

Mapping 是定义文档如何储存与索引,就跟 MySQL 中定义表结构一样

示例:

  1. PUT /my-index
  2. {
  3. "mappings": {
  4. "properties": {
  5. "age": {
  6. "type": "integer" },
  7. "email": {
  8. "type": "keyword" },
  9. "name": {
  10. "type": "text" }
  11. }
  12. }
  13. }

该示例创建了一个名为 my-index 的索引,有三个映射,分别是 ageemailname

Mapping 中的字段类型一旦设定后,禁止直接修改,原因是 Lucene 实现的倒排索引生成后不允许修改,如果修改必须重新建立新的索引,然后做 reindex 操作。

如果你想要一个字段只用于储存,而不被索引或搜索等,可以将 index 设置为 false

  1. PUT /my-index/_mapping
  2. {
  3. "properties": {
  4. "employee-id": {
  5. "type": "keyword",
  6. "index": false
  7. }
  8. }
  9. }

这样 employee-id 字段就会被存储,但不会被索引和搜索

查看索引的映射

  1. GET /索引名/_mapping

如果想查询特定字段的映射

  1. GET /索引名/_mapping/field/字段名

虽然 mapping 不能修改,但是可以新增字段,通过 dynamic 参数来控制字段的新增

  • true :(默认) 允许自动新增字段
  • false :不允许自动新增字段,但文档可以正常发写入,但无法对新增的字段进行查询操作
  • strict:文档不能写入,报错

自动新增字段就是在存入文档的时候如果有未定义的字段,会直接帮你自动新增字段映射

使用示例

  1. PUT /my-index
  2. {
  3. "mappings": {
  4. "dynamic": false,
  5. "properties": {
  6. "age": {
  7. "type": "integer" },
  8. "email": {
  9. "type": "keyword" },
  10. "name": {
  11. "type": "text" }
  12. }
  13. }
  14. }

mapper 的参数有很多,详情可看官方文档

传送门

settings(索引设置)

static

只能在创建索引时或关闭的索引上设置

  • index.number_of_shards:主分片数量,默认 1
  • index.number_of_routing_shards:拆分索引的路由分片数量,默认值位于 2~1024 之间,依赖索引主分片数量
  • index.shard.check_on_startup:打开前检查分片是否损坏,默认 false
  • index.codec:压缩存储算法,默认 LZ4
  • index.routing_partition_size:自定义路由可以到达的分片数量,默认 1
dynamic

可以使用 API 实时对索引进行操作

  • index.number_of_replicas:主分片的副本数,默认 1
  • index.auto_expand_replicas:根据集群中数据节点的数量自动扩展副本的数量,默认 false
  • index.search.idle.after:搜索空闲之前不能接收搜索和获取请求的时间,默认 30s
  • index.refresh_interval:刷新操作频率,最近对索引的更改既可见,默认 1s。-1 关闭刷新操作
  • index.max_result_window:查询索引结果的最大数量,默认 10000
  • index.max_inner_result_window:内部或聚合命中最大数量,默认 100
  • index.max_rescore_window:打分请求的最大索引数量,默认 10000(同 index.max_result_window)
  • index.max_docvalue_fields_search:查询中允许的最大字段数,默认 100
  • index.max_script_fields:查询中允许的最大脚本字段数,默认 32
  • index.query.default_field:查询返回的默认字段,默认*(表示所有)

示例:

  1. PUT /twitter
  2. {
  3. "settings" : {
  4. "number_of_shards" : 3,
  5. "number_of_replicas" : 2
  6. }
  7. }

查看设置

  1. GET /<target>/_settings
  2. GET /<target>/_settings/<setting>

查看索引

语法:GET /<target>

target 就是查询目标,可以查询多个(逗号分割),可以使用通配符 * , _all

示例

  1. # 查询 bank 索引
  2. GET /bank
  3. # 查询 bank 索引与 my-index 索引
  4. GET /bank,my-index
  5. # 查询以 my 开头的索引
  6. GET /my*
  7. # 查询 bank 索引与 my 开头的索引
  8. GET /bank,my*

查询所有索引

  1. GET /*

或者

  1. GET /_all

删除索引

语法:DELETE /<index>

示例:

  1. DELETE /my-index

这样就删除了 my-index 索引

也可以删除多个索引,以逗号分割就可以了

  1. DELETE /my-index,my-index1

还可以删除全部索引

  1. DELETE /_all

打开/关闭索引

一旦索引被关闭,那么这个索引只能显示元数据信息,不能够进行读写操作

关闭索引语法:POST /<index>/_close
打开索引语法:POST /<target>/_open

这里的路径参数 indextarget 是一样的,都可以是以逗号分割的索引列表或者表达式

示例

关闭索引 my-index

  1. POST /my-index/_close

打开索引

  1. POST /my-index/_open

操作多个

关闭 my-indexbank

  1. POST /my-index,bank/_close

关闭 my 开头的

  1. POST /my*/_close

关闭所有

  1. POST /*/_close
  2. # 或者
  3. POST /_all/_close

索引别名

索引别名大部分内容来自:博客园 - 奥辰

索引别名的官方文档:传送门

ES 中可以为索引添加别名,一个别名可以指向到多个索引中,同时在添加别名时可以设置筛选条件,指向一个索引的部分数据,实现在关系数据库汇总的视图功能,这就是 ES 中别名的强大之处。别名是一个非常实用的功能,为我们使用索引提供了极大的灵活性,许多 ES 的 API 都支持用别名来代替真实索引名。通过索引我们可以方便的进行以下操作:

  • 实现正在云心的集群上的一个索引到另一个索引之间的无缝切换。试想一下这种藏进,由于业务变换,我们需要将业务数据有索引 1 变换到新的索引 2 上,如果没有别名,我们必须修改和总段业务系统,但是有了别名,只需要修改别名,另起指向新的索引 2 即可,这样的操作可以在用户无任何感知的情况下完成。
  • 使数据检索等炒作更加方便。加入有两个月的日志数据,分别存放在 index_202008 和 index_202009 两个索引中,没有使用别名进行检索时,我们需要同时写上两个索引名称进行检索,使用索引后,我们可以令别名同时指向这两个索引,检索时只需要使用这个别名就可以同时在两个索引中尽心检索。
  • 为一个索引中的部分数据创建别名,例如,一个索引中存放了一整年的数据,现在新增一个业务场景,更多的是对其中某一个月的数据进行检索,这时,我们可以在创建别名时,通过设置过滤条件 filter,可以单独令别名指向一个月的数据,使得检索更加高效。

通过上面的场景我们可以看出,ES 中别名可以指向一个索引,也可以同时指向多个索引,甚至可以通过配合过滤器 filter 指向索引中部分数据。别名可以再创建索引时添加,也可以在索引创建后进行添加,ES 中提供丰富的 API 对别名进行管理。

创建别名

创建别名有很多种方法,可以创建索引同时创建别名,也可以在创建索引后创建,既可以让别名指向多个索引,也可以让别名指向一个索引的部分数据,甚至指向一个字段。我们来一一例举这是如何操作的。

创建索引同时创建别名

例子:创建一个名为 users 用户索引,索引中记录了用户出生年,现在,我们在创建索引的同时,创建两个别名,一个别名指向整个 users 索引,并通过 filter 进行过滤,使别名只指向 2000 年出生的用户。

  1. PUT /users
  2. {
  3. "mappings":{
  4. "properties":{
  5. "birth-year":{
  6. "type":"integer"}
  7. }
  8. }
  9. aliases":{
  10. "myusers":{
  11. }
  12. "2000":{
  13. "filter":{
  14. "term":{
  15. "birth-year":2000}
  16. }
  17. }
  18. }
  19. }

其中 别名 myusers 指向整个 users 索引,别名 2000 只指向 2000 年出生的用户

创建索引后创建别名

直接通过 API 路由传递别名来创建,这种方法有一下几种请求方式,注意,这种方式要求索引必须存在。

  1. PUT /<index>/_alias/<alias>
  2. POST /<index>/_alias/<alias>
  3. PUT /<index>/_aliases/<alias>
  4. POST /<index>/_aliases/<alias>

可以通过请求体来对别名进行设置,例如创建一个名为 2020 的别名,指向 users 索引中 birth-year 字段值为 2020 的文档。

  1. PUT /users/alias/2020
  2. {
  3. "filter":{
  4. "term":{
  5. "birth-year" : 2020
  6. }
  7. }
  8. }
创建字段别名

索引可以拥有别名,字段也可以,在创建索引时,我们可以为字段设置一个别名。例如,为 username 字段设置一个别名 name。

  1. PUT /users
  2. {
  3. "mappings":{
  4. "properties":{
  5. "username":{
  6. "type":"keyword"
  7. },
  8. "name":{
  9. "type":"alias",
  10. "path":"username"
  11. }
  12. }
  13. }
  14. }

修改、删除

之所在现在要将修改别名和删除出别名放在一起来说,是因为下面的这个 API 功能太多,既能够添加别名,也能修改别名,还能删除别名。 API 文档

新增别名

  1. POST _aliases
  2. {
  3. "actions": [
  4. {
  5. "add": {
  6. "index": "my-data-stream",
  7. "alias": "my-alias",
  8. "filter":{
  9. "term":{
  10. "birth-year" : 2020
  11. }
  12. }
  13. }
  14. }
  15. ]
  16. }

actions 是一组操作集合,可以是 addremove

add 是添加操作,remove 是删除操作

index 是索引名 alias 是别名,还有其他参数可参阅API 文档

删除别名
  1. POST _aliases
  2. {
  3. "actions": [
  4. {
  5. "remove": {
  6. "index": "my-data-stream",
  7. "alias": "my-alias"
  8. }
  9. }
  10. ]
  11. }

这个 API 形式上很好理解,就是想aliases路由发送一个 POST 请求,别名的信息都是在请求体中进行配置,actions表示需要进行的操作,里面每一个子项都表示一个动作,这个动作可以为add表示添加别名的操作,remove表示删除别名的操作。index表示针对哪一个索引上创建别名,alias后面跟着的就是新建或者需要删除的别名的名称。下面通过一些例子说明如何使用这一 API。

为同一索引创建多个别名
  1. POST /_aliases
  2. {
  3. "actions" : [
  4. {
  5. "add" : {
  6. "index" : "users", "alias" : "alias1"}},
  7. {
  8. "add": {
  9. "index" : "users", "alias" : "alias2"}}
  10. ]
  11. }
删除一个别名
  1. POST /_aliases
  2. {
  3. "actions" : [
  4. {
  5. "add": {
  6. "index" : "users", "alias" : "alias2"}}
  7. ]
  8. }
重命名一个别名

ES 中别为提供直接进行重命名操作的关键字,而是先执行 remove,然后执行 add,这一操作是原子操作,所以无需担心别名删除未创建的短暂中空期,这相当于为为原来别名创建了一个新的引用,删除旧的应用,实际还是同一个别名,例如将名为 alias1 的别名重命名为 alias2,可以这么操作:

  1. POST /_aliases
  2. {
  3. "actions" : [
  4. {
  5. "remove" : {
  6. "index" : "users", "alias" : "alias1"}},
  7. {
  8. "add": {
  9. "index" : "users", "alias" : "alias2"}}
  10. ]
  11. }
创建一个别名指向多个索引

例如创建一个名为 myusers 的别名同时指向索引 users1 和 users2:

  1. POST /_aliases
  2. {
  3. "actions" : [
  4. {
  5. "add": {
  6. "indices" : ["users1","users2"], "alias" : "myusers"}}
  7. ]
  8. }

也可以通过通配符来实现这一操作:

  1. POST /_aliases
  2. {
  3. "actions" : [
  4. {
  5. "add": {
  6. "indices" : ["users*"], "alias" : "myusers"}}
  7. ]
  8. }
创建有过滤条件的别名
  1. POST /_aliases
  2. {
  3. "actions" : [
  4. {
  5. "add": {
  6. "indices" : ["users*"],
  7. "alias" : "myusers",
  8. "filter":{
  9. "term":{
  10. "birth-year" : 2020
  11. }
  12. }
  13. }
  14. }
  15. ]
  16. }
创建可写入别名

如果一个别名单独指向一个索引,那么使用别名进行写入操作是不会有问题的,但是,一个别名指向多个索引索引时,是不能进行写入操作,因为 ES 不知道将文档写入到哪一个索引。这一问题可以在创建别名时将某一个索引设置为可写来解决,注意,只能设置一个。

  1. POST /_aliases
  2. {
  3. "actions" : [
  4. {
  5. "add" : {
  6. "index" : "users1","alias" : "myusers" ,"is_write_index": true }},
  7. {
  8. "add": {
  9. "index" : "users2", "alias" : "myusers"}}
  10. ]
  11. }

查看索引别名

查看别名是否存在

使用 HEAD 请求方式 + 别名可以查看别名是否存在:

  1. HEAD /_alias/<alias>
  2. HEAD /<index>/_alias/<alias>

如果是查看某个索引是否有某个别名,可以这么操作:

  1. HEAD /users/_alias/myusers1

users 是索引名,myusers1 是别名

查看别名信息
  1. GET /_cat/aliases/<alias>
  2. GET /_cat/aliases

前者查看指定别名,后者查看集群中所有别名


索引模板与组件模板

官方文档在这 : 官方文档

索引模板:就是把已经创建好的某个索引的参数设置 (settings) 和索引映射 (mapping) 保存下来作为模板,在创建新索引时,指定要使用的模板名,就可以直接重用已经定义好的模板中的设置和映射。

模板有两种类型:索引模板组件模板

  1. 组件模板是可重用的构建块,用于配置映射,设置和别名;它们不会直接应用于一组索引。
  2. 索引模板可以包含组件模板的集合,也可以直接指定设置,映射和别名。

Elasticsearch 具有内置索引模板,每个索引模板的优先级为 100,适用于以下索引模式:

  • logs-*-*
  • metrics-*-*
  • synthetics-*-*

组件模板

创建

语法:PUT /_component_template/<component-template>

路径参数 component-template 就是要创建的组件模板的名称

Elasticsearch 具有内置组件模板

  • logs-mappings
  • logs-settings
  • metrics-mappings
  • metrics-settings
  • synthetics-mapping
  • synthetics-settings

Elastic Agent 是使用这些模板进行配置的,如果希望覆盖这些模板,就需要把 version 参数定得比内置的高

创建组件模板支持这些参数

  • template

    • aliases :索引别名参数
    • mappings:索引映射关系
    • settings:索引设置
  • version:组件模板的版本,会使用高版本的,没有默认值
  • _meta :该索引模版的用户元数据配置,可以存放任何数据,是一个对象类型,比如可以写注释等
  • allow_auto_create:覆盖集群配置 action.auto_create_index

使用示例

  1. PUT _component_template/template_1
  2. {
  3. "template": {
  4. "settings" : {
  5. "number_of_shards" : 1
  6. },
  7. "aliases" : {
  8. "alias1" : {
  9. },
  10. "alias2" : {
  11. "filter" : {
  12. "term" : {
  13. "user.id" : "kimchy" }
  14. },
  15. "routing" : "shard-1"
  16. },
  17. "{index}-alias" : {
  18. }
  19. },
  20. "version": 123,
  21. },
  22. "_meta": {
  23. "description": "set number of shards to one",
  24. "serialization": {
  25. "class": "MyComponentTemplate",
  26. "id": 10
  27. }
  28. }
  29. }

其中 {index} 会替换成你创建的索引的名称

查询

语法:GET /_component_template/<component-template>

路径参数 <component-template> 是组件模板的名称或者表达式,可以查询多个(使用逗号分割),可以使用通配符 *

示例

  1. GET /_component_template/temp*

获取所有组件模板

  1. GET /_component_template
修改

直接起相同名字的覆盖就完事了

删除

语法:DELETE /_component_template/<component-template>

路径参数 <component-template> 是组件模板的名称或者表达式,可以查询多个(使用逗号分割),可以使用通配符 *

示例

  1. DELETE /_component_template/temp*

索引模板

创建索引模板

语法:PUT /_index_template/<index-template>

index-template 是组件模板的名称

请求体的话有这些参数

  • composed_of :(可选)组件模板的名称集合,是个字符串数组,这些组件模板是按顺序合并的,也就是说越后面的组件模板优先级越高
  • data_stream :(可选)如果包含此对象,则使用模板创建数据流及其备份索引。支持空对象。
  • index_patterns:(必选)字符串数组,使用通配符定义匹配索引的规则
  • template

    • aliases :索引别名参数
    • mappings:索引映射关系
    • settings:索引设置
  • priority :(可选)模板的优先级,默认为 0,创建新索引时会使用优先级高的模板
  • version:组件模板的版本,会使用高版本的,没有默认值
  • _meta :该索引模版的用户元数据配置,可以存放任何数据,是一个对象类型,比如可以写注释等

示例:

  1. PUT /_index_template/template_1
  2. {
  3. "index_patterns" : ["t*"],
  4. "priority" : 0,
  5. "template": {
  6. "settings" : {
  7. "number_of_shards" : 1,
  8. "number_of_replicas": 0
  9. },
  10. "mappings" : {
  11. "_source" : {
  12. "enabled" : false }
  13. }
  14. }
  15. }
  16. PUT /_index_template/template_2
  17. {
  18. "index_patterns" : ["te*"],
  19. "priority" : 1,
  20. "template": {
  21. "settings" : {
  22. "number_of_shards" : 2
  23. },
  24. "mappings" : {
  25. "_source" : {
  26. "enabled" : true }
  27. }
  28. }
  29. }

现在这种情况,如果使用 te 开头的索引会使用模板 template_2 因为它优先级高

  1. PUT /_component_template/template_with_2_shards
  2. {
  3. "template": {
  4. "settings": {
  5. "index.number_of_shards": 2
  6. }
  7. }
  8. }
  9. PUT /_component_template/template_with_3_shards
  10. {
  11. "template": {
  12. "settings": {
  13. "index.number_of_shards": 3
  14. }
  15. }
  16. }
  17. PUT /_index_template/template_1
  18. {
  19. "index_patterns": ["t*"],
  20. "composed_of": ["template_with_2_shards", "template_with_3_shards"]
  21. }

这样,匹配 t* 这个表达式的索引(例如:te)将会有三个主分片,因为template_with_3_shards 的优先级更高

删除索引模板

语法: DELETE /_component_template/<component-template>

路径参数component-template是需要删除的索引模板的名称,可以是表达式,可以说多个(逗号分割)

发表评论

表情:
评论列表 (有 0 条评论,87人围观)

还没有评论,来说两句吧...

相关阅读