暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

ElasticSearch核心知识点之Mapping

Code视角 2021-12-19
783

大纲

关注公众号即可获取上百本前沿技术电子书、最新面试资料。

Mapping基础使用

「Mapping概念」
Mapping是Elasticsearch中一个非常重要的概念,它定义了搜索引擎应该如何存储和搜索文档及其字段。

在Elasticsearch中有两种映射方式:Dynamic mapping(动态映射)Explicit mapping (显式映射)。

  • 动态映射:当 Elasticsearch 在文档中检测到新字段时,它默认动态地将该字段添加到类型映射中。我们只需要创建index就行,无需关系映射字段。

  • 显示映射:显式映射可以让我们预先定义好字段类型,避免出现错误的数据插入,导致脏数据,比如日期格式,文本是否需要全文检索等。下文简单的demo创建

「MappingCRUD」

  1. 查看type
GET /my-index-000001/_mapping

// 返回诗句
{
  "my-index-000001" : {
    "mappings" : { 
      "properties" : { // 字段映射
        "age" : {
          "type" : "integer"
        },
        "email" : {
          "type" : "keyword"
        },
        "employee-id" : {
          "type" : "keyword",
          "index" : false
        },
        "name" : {
          "type" : "text"
        }
      }
    }
  }
}


  1. 创建
PUT /my-index-000001
{
    "mappings":{
        "MyTypeName":{  // type 名称
            "properties":{
                "age":{
                    "type":"integer"
                },
                "email":{
                    "type":"keyword"
                },
                "name":{
                    "type":"text"
                }
            }
        }
    }
}



  1. 添加字段
PUT /my-index-000001/_mapping/MyType
{
  "properties": {
    "employee-id": {
      "type""keyword",
      "index"false
    }
  }
}

  1. 修改 暂不支持

「Elasticsearch元字段」

每个文档都有和index、type关联的元数据,例如_index、mapping _type和_id元数据字段。在创建Mapping时,可以自定义其中一些元数据字段的行为。例如:如果存储网页数据时,就可以禁用_source。

  1. 基础标识元字段
字段含义
_index文档所属的索引。
_type文档的映射类型。
_id文档的id。
  1. 文档源元数据字段
字段含义
_source表示文档正文的原始 JSON。
_size_source由mapper-size插件提供 的字段大小(以字节为单位)。
  1. 文档计数元数据字段
字段含义
_doc_count当文档表示预聚合数据时,用于存储文档计数的自定义字段。
  1. 路由元数据字段
字段含义
_routing将文档路由到特定分片的自定义路由值。
  1. 索引元数据字段
字段含义
_field_names文档中包含非空值的所有字段。
_ignored文档中的ignore_malformed。
  1. 其他元数据字段
字段含义
_meta应用程序特定的元数据。
_tier文档所属索引的当前数据层首选项。

「Mapping字段参数」

字段参数和Field datatypes是相互结合的,主要就是用来各个数据类型的mapping定义过程。很多参数只对一些数据类型是适用的

  1. analyzer

analyzer参数指定索引或搜索字段时用于 文本分析的分析器,只有text类型字段支持该参数。官方文档详解:https://www.elastic.co/guide/en/elasticsearch/reference/7.15/analyzer.html

  1. coerce

强制尝试清理脏值以适应字段的数据类型。例如:

字符串将被强制转换为数字。对于整数值,浮点数将被截断。官方文档详解:https://www.elastic.co/guide/en/elasticsearch/reference/7.15/coerce.html

  1. copy_to

copy_to参数允许您将多个字段的值复制到一个组字段中,然后可以将其作为单个字段进行查询。经常搜索多个字段,可以使用copy_to搜索较少的字段来提高搜索速度 。官方文档详解:https://www.elastic.co/guide/en/elasticsearch/reference/7.15/copy-to.html

  1. doc_values

Doc Values本质上是一个序列化了的列式存储结构,非常适合排序、聚合以及字段相关的脚本操作。而且这种存储方式便于压缩,尤其是数字类型。压缩后能够大大减少磁盘空间,提升访问速度。其实就是es在构建倒排索引的同时,构建了正排索引,保存了docId到各个字段值的映射,可以看作是以文档为维度,从而实现根据指定字段进行排序和聚合的功能。官方文档详解:https://www.elastic.co/guide/en/elasticsearch/reference/7.15/doc-values.html

  1. dynamic

dynamic参数控制是否动态添加新字段,并接受以下参数 true, runtime, false, strict. 官方文档详解:https://www.elastic.co/guide/en/elasticsearch/reference/7.15/dynamic.html

  1. eager_global_ordinals

是否开启全局预加载,加快查询;此参数只支持text和keyword,keyword默认可用,而text需要设置fielddata属性  官方文档详解:https://www.elastic.co/guide/en/elasticsearch/reference/7.15/eager-global-ordinals.html

  1. enabled

是否对当前字段建立索引,对于只进行存储的字段,无需建立索引浪费存储空间。官方文档详解:https://www.elastic.co/guide/en/elasticsearch/reference/7.15/enabled.html

  1. fielddata

  2. fields

某个字段具有多个映射属性的时候,可以通过这个参数设置,例如 name 既可以全文检索又可以精准匹配时可以使用此参数设置。官方文档详解:https://www.elastic.co/guide/en/elasticsearch/reference/7.15/multi-fields.html

  1. format

该参数可以把JSON中的字符串时间数据进行格式化。官方文档详解:https://www.elastic.co/guide/en/elasticsearch/reference/7.15/mapping-date-format.html

  1. ignore_above

长度超过ignore_above设置的字符串将不会被索引或存储。对于字符串数组,ignore_above将分别应用于每个数组元素,并且长度超过的字符串元素ignore_above不会被索引或存储。

官方文档详解:https://www.elastic.co/guide/en/elasticsearch/reference/7.15/ignore-above.html

  1. ignore_malformed

对插入字段进行类型校验,必须是指定类型,否者进行存储。例如 官方文档详解:https://www.elastic.co/guide/en/elasticsearch/reference/7.15/ignore-malformed.html

  1. index_options

该参数仅用于text字段,控制将哪些信息添加到倒排索引以进行搜索和突出显示。

官方文档详解:https://www.elastic.co/guide/en/elasticsearch/reference/7.15/index-options.html

  1. index_phrases

term两两合并,便于短语精准查询,尤其是停用词没有被移出的情况下。

官方文档详解:https://www.elastic.co/guide/en/elasticsearch/reference/7.15/index-phrases.html

  1. index_prefixes

索引前缀,该参数如果开启可以加快短语前缀匹配,可接受参数:min_chars

索引的最小前缀长度。必须大于 0,默认为 2。该值包含在内。

max_chars

索引的最大前缀长度。必须小于 20,默认为 5。该值包含在内。

官方文档详解:https://www.elastic.co/guide/en/elasticsearch/reference/7.15/index-prefixes.html

  1. index

index选项控制是否对字段值进行索引。它接受true 或false并默认为true。未编入索引的字段不可查询。

官方文档详解:https://www.elastic.co/guide/en/elasticsearch/reference/7.15/mapping-index.html

  1. meta

附加到字段的元数据。此元数据对 Elasticsearch 是不透明的,它仅适用于处理相同索引的多个应用程序共享有关字段(例如单位)的元信息

官方文档详解:https://www.elastic.co/guide/en/elasticsearch/reference/7.15/mapping-field-meta.html

  1. normalizer

normalizer是 keyword的一个属性,可以对 keyword生成的单一 Term再做进一步的处理,比如 lowercase,即做小写变换。使用方法和自定义分词器有些类似,需要自定义

官方文档详解:https://www.elastic.co/guide/en/elasticsearch/reference/7.15/normalizer.html

  1. norms

可以使用更新映射 API在现有字段上禁用规范。

官方文档详解:https://www.elastic.co/guide/en/elasticsearch/reference/7.15/norms.html

2o. null_value

一个null值不能被索引或搜索。当一个字段设置为null, (或一个空数组或一个null值数组)时,它被视为该字段没有值。

该null_value参数允许您null用指定的值替换显式值,以便可以对其进行索引和搜索。类似 is null.

官方文档详解:https://www.elastic.co/guide/en/elasticsearch/reference/7.15/null-value.html

  1. position_increment_gap

该设置告诉 Elasticsearch 应该为数组中每个新元素增加当前词条 position 的指定值。

官方文档详解:https://www.elastic.co/guide/en/elasticsearch/reference/7.15/position-increment-gap.html

  1. properties

当前字段是object类型或者nested类型时,必须映射其子字段类型。就是为子文档字段做映射。

官方文档详解:https://www.elastic.co/guide/en/elasticsearch/reference/7.15/properties.html

  1. search_analyzer

对当前字段查询设置分词器。

官方文档详解:https://www.elastic.co/guide/en/elasticsearch/reference/7.15/search-analyzer.html

  1. similarity

es中内置的相似度设置。开箱即用。

官方文档详解:https://www.elastic.co/guide/en/elasticsearch/reference/7.15/similarity.html

  1. store

是否在_source文档之外再进行额外存储。

官方文档详解:https://www.elastic.co/guide/en/elasticsearch/reference/7.15/mapping-store.html

  1. term_vector

termvector会获取document中的某个field内的各个term的统计信息,该属性的取值可以为no(默认值)、yes、with_offsets、with_positions、with_positions_offsets。该属性表示是否对该字段计算lucene词向量,如果使用的是高亮则需要计算词向量。

官方文档详解:https://www.elastic.co/guide/en/elasticsearch/reference/7.15/term-vector.html

Mapping之优化设置&面试题

「Mapping限制设置」
ElasticSearch对mapping做了映射保护,防止mapping 爆炸。通过以下参数进行设置。

  1. index.mapping.total_fields.limit:索引中的最大字段数。字段和对象映射以及字段别名计入此限制。默认值为1000。
PUT test_index/_settings
{
    "index.mapping.total_fields.limit"2000  // 数量
}

  1. index.mapping.depth.limit:字段的最大深度,以内部对象的数量来衡量。例如,如果所有字段都是在根对象级别定义的,则深度为1。如果有一个对象映射,则深度为 2,等等。默认值为20
PUT test_index/_settings
{
    "index.mapping.depth.limit"20  // 数量
}

  1. index.mapping.nested_fields.limit: nested索引中的最大字段数,默认为50。使用100个嵌套字段索引1个文档实际上索引101个文档,因为每个嵌套文档都被索引为单独的隐藏文档
PUT test_index/_settings
{
    "index.mapping.nested_fields.limit"100  // 数量
}

  1. index.mapping.nested_objects.limit:单个文档可以包含的所有nested类型的嵌套 JSON 对象的最大数量 。当文档包含太多嵌套对象时,此限制有助于防止出现内存不足错误。默认为10000
PUT test_index/_settings
{
    "index.mapping.nested_objects.limit"10000  // 数量
}

  1. index.mapping.field_name_length.limit:设置字段名称的最大长度。此设置并不是真正解决映射爆炸的问题,通常不需要设置此设置。除非我们开始添加大量名称非常长的字段,否则默认值是可以的。默认为 Long.MAX_VALUE(无限制)
PUT test_index/_settings
{
    "index.mapping.field_name_length.limit"1000000  // 数量
}

6.number_of_shards:数据分片数,默认为5。

PUT test_index/_settings
{
    "number_of_shards"5  // 数量
}

7.number_of_replicas:数据备份数,如果只有一台机器,设置为0。

PUT test_index/_settings
{
    "number_of_replicas"1  // 数量
}

「面试题为什么删除MappingTypes or 为什么删除type」

  1. 首先我们要知道什么是MappingType?

从 Elasticsearch 的第一个版本开始,每个文档都存储在一个索引中并分配了一个type。映射类型用于表示被索引的文档或实体的类型,例如 twitter索引可能具有user类型和tweet类型。

每个type都可以有自己的字段,因此user类型可能有一个 full_name字段、一个user_name字段和一个email字段,而 tweet类型可以有一个content字段、一个tweeted_at字段以及与user类型一样的 user_name字段。

每个文档都有一个_type包含类型名称的元数据字段,通过在 URL 中指定类型名称,可以将搜索限制为一种或多种类型:例如:

GET twitter/user,tweet/_search
{
  "query": {
    "match": {
      "user_name""kimchy"
    }
  }
}

_type字段与文档的_id字段组合生成一个_uid字段,来进行分片,因此同一_id索引中可以存在不同类型的文档。

  1. 为什么要删除?

最初Elasticsearch中“索引”类似于 SQL 数据库中的“数据库”,而“type”等同于“表”。但是在 SQL 数据库中,表是相互独立的。一个表中的列与另一表中同名的列没有关系。

而在Elasticsearch索引中,不同type中具有相同名称的字段在内部由相同的 Lucene 字段支持。例如:一个index中有两个type serType 和 tweetType,如果两个类型中都有相同的字段‘user_name’时候,这个字段的定义必须相同(如果两个类型中的字段类型不一样就无法处理),所以对于‘type’来说就不是一个表,之间存在绝对的耦合关系。最重要的原因是:在同一索引中存储具有很少或没有共同字段的不同实体会导致数据稀疏并干扰 Lucene 有效压缩文档的能力。

3.type什么版本移除的?

版本内容
5.6.0index.mapping.single_type: true 强制使用单一type,6.0后强制执行。建议join 字段代替父子文档
6.x每个索引只允许一个Type, 不在支持父子文档,使用join字段类型。
7.x不推荐在请求中指定类型,_default_映射类型被去除,索引创建、索引模板和typeapi中的include_type_name参数将默认为false。设置该参数将导致一个弃用警告。
8.x不再支持在请求中指定type。include_type_name参数被删除。
关注公众号,带你学习ElasticSearch。
文章转载自Code视角,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论