zl程序教程

您现在的位置是:首页 >  数据库

当前栏目

Elasticsearch语法知多少之Template

elasticsearch 语法 Template 知多少
2023-09-27 14:28:03 时间

目录

目标

ES版本信息

官方文档

相关概念

索引模板实战

创建索引模板

比较索引模板和静态映射的优先级

删除索引模板

查询索引模板

修改模板

动态模板实战

转换字段类型(根据字段名称匹配)

对多级字段的支持(根据字段名称和路径匹配)

对copy_to的支持

对对象的支持


目标

  • 熟悉模板的使用方法,包括索引模板和动态模板。
  • 熟悉索引模板匹配顺序、索引模板匹配规则、配置数据类型自动探测功能,通过索引模板或动态模板实现字段类型转换等操作。

ES版本信息

7.17.5


官方文档

Index templateshttps://www.elastic.co/guide/en/elasticsearch/reference/7.17/index-templates.html#index-templates

Dynamic mappinghttps://www.elastic.co/guide/en/elasticsearch/reference/7.17/dynamic-mapping.html


相关概念

索引模板和动态模板的区别

  1. 匹配粒度不同:索引模板匹配粒度是索引,动态模板匹配的是某一个索引下面文档的字段。
  2. 创建方法不同:索引模板需要创建索引模板来实现,动态模板需要创建索引实现。
  3. 功能不同:索引模板针对索引进行通用配置,动态模板针对某一个索引下文档的字段进行通用配置。

索引模板优先级

可以建立多个索引模板,为了明确模板匹配的顺序,ES通过order字段实现索引顺序匹配。order越小匹配顺序优先级越高,也就是说,如果索引模板配置了相同的属性,order大的索引模板会覆盖order小的索引模板。

数据类型自动探测

ES的动态映射机制使得索引文档时字段能被自动识别出类型,比如"2022-01-02"自动识别为date类型。

索引模板和静态映射的优先级

如果索引模板和静态映射匹配了相同的属性,则以静态映射为准。比如索引模板设置日期类型不被自动探测,而静态映射设置日期类型能被自动探测。

避免索引模式冲突
Elasticsearch 具有内置索引模板,以下索引的优先级为100:

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

Elastic Agent使用这些模板来创建数据流。由 Fleet 集成创建的索引模板使用类似的重叠索引模式,并且优先级高达200。如果使用 Fleet或Elastic Agent,要将索引模板优先级设置低于100以避免覆盖这些模板。否则的话还要进行其他配置,而在生产环境中往往不会大规模建立模板。


索引模板实战

创建索引模板

需求:创建两个索引模板,观察两个索引模板是否生效,以及索引模板匹配的优先级。

第一步:创建两个模板。

  • main_template的index_patterns为*表示匹配所有索引;my_template_1的index_patterns为books*表示匹配books开头的索引。
  • order越小匹配顺序优先级越高,也就是说,如果索引模板配置了相同的属性,order大的索引模板会覆盖order小的索引模板。
  • main_template开启日期数据类型自动探测,my_template_1关闭了日期数据类型自动探测。
PUT /_template/main_template
{
  "index_patterns": [
    "*"
  ],
  "order": 0,
  "settings": {
    "number_of_replicas": 1,
    "number_of_shards": 1
  },
  "mappings": {
    "date_detection": true
  }
}

PUT /_template/my_template_1
{
  "index_patterns": [
    "books*"
  ],
  "order": 1,
  "mappings": {
    "date_detection": false
  }
}

第二步:创建索引并索引文档。

PUT /books_db

PUT /books_db/_doc/1
{
  "book_no": 100001,
  "book_name": "凡人修仙传",
  "price":19.9,
  "create_time": "2022-01-01"
}

第三步:查看索引的映射情况。发现create_time为text类型,说明:

  • 索引生效了,因为根据动态映射规则,"2022-01-01"会被映射为date类型。
  • main_template先于my_template_1匹配到索引,my_template_1的配置覆盖了main_template的配置。
GET /books_db/_mapping

比较索引模板和静态映射的优先级

方案:根据上面两个模板的配置,创建一个模板,将date_detection设置为true,如果日期类型的字符串可以被映射为date类型就可以证明静态映射的优先级>索引模板的优先级。

第一步:创建索引。开启日期类型自动探测。

PUT /books_db_2
{
  "mappings": {
    "date_detection" : true
  }
}

第二步:索引文档。发现日期类型的字符串可以被映射为date类型,即证明了静态映射的优先级>索引模板的优先级。

GET /books_db_2/_mapping

删除索引模板

DELETE /_template/my_template_1

查询索引模板

#查询单个模板
GET /_template/main_template
#模糊查询
GET /_template/my*

修改模板

POST /_template/main_template
{
  "index_patterns": [
    "*"
  ],
  "order": 0,
  "mappings": {
    "date_detection": false
  }
}

动态模板实战

转换字段类型(根据字段名称匹配)

第一步:创建索引。说明:

  • dynamic_templates下可以创建多个模板对象。
  • 一共创建了两个模板,模板名称分别是string_to_boolean和string_to_keyword。
  • string_to_boolean功能:类型为string类型且以is_开头且不以_text结尾,就将这个字段映射为boolean类型。
  • string_to_keyword功能:将所以string类型映射为keyword类型。
PUT /movies_db
{
  "mappings": {
    "dynamic_templates": [
      {
        "string_to_boolean": {
          "match_mapping_type": "string",
          "match": "is_*",
          "unmatch": "*_text",
          "mapping": {
            "type": "boolean"
          }
        }
      },
      {
        "string_to_keyword": {
          "match_mapping_type": "string",
          "mapping": {
            "type": "keyword"
          }
        }
      }
    ]
  }
}

第二步:索引文档。

PUT /movies_db/_doc/1
{
  "user_name": "张三",
  "is_adult": "true",
  "is_adult_text": "未成年人",
  "age":12
}

第三步:查看文档和映射情况,发现字段确实转换成了动态模板所设置的类型。

GET /movies_db/_doc/1

GET /movies_db/_mapping

对多级字段的支持(根据字段名称和路径匹配)

对copy_to的支持

需求:使用动态模板,通过字段名称和路径实现copy_to功能。

第一步:创建索引。说明:

  • full_address_template设定address_list字段下除了county这个叶子字段外,其他字段都匹配,这些字段会复制到full_address字段上;
  • 设定ik分词器
PUT my-index-000001
{
  "mappings": {
    "dynamic_templates": [
      {
        "full_address_template": {
          "path_match": "address_list.*",
          "path_unmatch": "*.county",
          "mapping": {
            "type": "text",
            "copy_to": "full_address"
          }
        }
      }
    ]
  },
  "settings": {
    "index": {
      "analysis.analyzer.default.type": "ik_max_word"
    }
  }
}

第二步:索引文档。

PUT my-index-000001/_doc/1
{
  "address_list": {
    "province":  "湖南省",
    "city": "长沙市",
    "county":   "天心区"
  }
}
PUT my-index-000001/_doc/2
{
  "address_list": {
    "province":  "湖南省",
    "city": "长沙市",
    "county":   "芙蓉区"
  }
}

PUT my-index-000001/_doc/3
{
  "address_list": {
    "province":  "广东省",
    "city": "广州市",
    "county":   "白云区"
  }
}

PUT my-index-000001/_doc/4
{
  "address_list": {
    "province":  "湖北省",
    "city": "武汉市",
    "county":   "江夏区"
  }
}

第三步:精确搜索文档,发现以县级作为条件查不到数据,由此可见匹配规则生效了。

GET my-index-000001/_search
{
  "query": {
    "term": {
      "full_address": "江夏"
    }
  }
}

GET my-index-000001/_search
{
  "query": {
    "term": {
      "full_address": "湖南"
    }
  }
}

对对象的支持

需求:使用动态模板,通过字段名称和路径转换对象的字段类型。

第一步:创建索引。说明:string_as_keyword模板将stu_files下的name字段设置为keyword类型。

PUT student_db
{
  "mappings": {
    "dynamic_templates": [
      {
        "string_as_keyword": {
          "match_mapping_type": "string",
          "path_match":   "stu_files.name",
          "mapping": {
            "type": "keyword"
          }
        }
      }
    ]
  }
}

第二步:索引文档。

PUT /student_db/_doc/1
{
  "stu_files": {
    "id_card": "499924199012124356",
    "long_id": "5645767567",
    "long_address_text": "湖南省长沙市天心区",
    "name": "张三"
  }
}

第三步:查看映射情况,发现stu_files下的name字段为keyword类型,测试通过。

GET /student_db/_mapping