ElasticSearch 的Mapping 和常见字段类型

ElasticSearch 的Mapping 和常见字段类型

  • 什么是 Mapping

    • Mapping 类似数据库中的 schema 的定义,作用如下:
      • 定义索引中的字段名称
      • 定义字段的数据类型,如 字符串,数字,布尔…
      • 字段、倒排索引的相关配置 (分不分词,分词器的选择等)
    • Mapping 会把 JSON 文档映射成 Lucene 所需要的扁平格式
    • 一个Mapping属于一个索引的 Type
      • 每个文档都属于一个Type
      • 一个 Type 有同一个 Mapping 定义
      • 7.0 开始,不需要在 Mapping 定义中指定 type 信息
  • 字段的数据类型

    • 简单类型
      • Text / Keyword
      • Date
      • Integer / Floating
      • Boolean
      • IPv4 & IPv6
    • 复杂类型 - 对象和嵌套对象
      • 对象类型 / 嵌套类型
    • 特殊类型
      • geo_point & geo_shape / percolator 地理信息
  • 什么是 Dynamic Mapping

    • 在写入文档的时候,如果索引不存在,会自动创建索引
    • Dynamic Mapping 的机制,使得我们可以无需手动定义 Mappings,ElasticSearch 会自动根据文档信息,推算出字段的类型,但是有时候会推算得不准
    • 当类型设置不对时,会导致一些功能无法正常运行,例如 Range 查询
  • ElasticSearch 类型的自动识别

    ElasticSearch 类型的自动识别是基于 JSON 的格式的

    JSON 类型ElasticSearch 类型
    字符串- 匹配日期格式,设置成 Date
    - 匹配数字设置为 float 或 long ,该选项默认关闭
    - 设置为 Text ,并且增加 keyword 子字段
    布尔值boolean
    浮点数float
    整数long
    对象Object
    数组由第一个非空数值的类型所决定
    空值忽略
  • 能否更改 Mapping 的字段类型

    • 新增字段

      • Dynamic 设为 true 时,有新增的字段写入, Mapping 也同时会更新
      • Dynamic 设为 false 时,Mapping 不会被更新,新增字段的数据无法被索引,但是字段信息会出现在 _source 中
      • Dynamic 设为 Strict ,文档写入失败
    • 对已有字段,一旦已经有数据写入,就不在支持修改字段定义

      • Lucene 实现的倒排索引,一旦生成后,就不允许修改
    • 如果希望改变字段类型,必须 Reindex API ,重建索引

    • 原因:

      • 如果修改了字段的数据类型,会导致已被索引的数据无法被搜索
      • 如果是新增的字段,就不会有这样的影响
    • 控制 Dynamic Mappings

    truefalsestrict
    文档可索引
    字段可更新
    Mapping 被更新
    • 当 dynamic 被设置成 false 时,新增字段数据,该数据可以存入es,但是该字段不能被搜索,mapping也不会更新
    • 当设置成 Strict 模式时,数据写入直接出错

    修改 dynamic 方法

    PUT movies/_mapping
    {
      "dynamic":true
    }
    

显式 Mapping 的设置及常见参数介绍

如何显式定义一个 Mapping

PUT movies
{
    "mappings":{
        // 定义内容
    }
}

自定义 Mapping 的一些建议

  • 可以参考 API 手册,纯手写
  • 可以为了减少输入的工作量,减少出错概率,可以依照以下步骤
    • 创建一个临时的 index ,写入一些样本数据
    • 通过访问 Mapping API 获取该 index 的动态 Mapping 定义
    • 修改后复制 JSON 定义,使用该配置创建索引
    • 删除临时索引

控制当前字段是否被索引

index 控制当前字段是否被索引。默认为 true 。

如果设置成 false,该字段不可被搜索

但是用其他字段搜索,该字段可见

PUT users
{
  "mappings":{
    "properties":{
      "firstName":{
          "type":"text"
      },
      "lastName":{
      	"type":"text"
  	  },
  	"mobile":{
      "type":"text",
      "index":false  # 该字段不可被搜索
      }
    }
  }
}

Index Options

  • 有四种级别的 Index Options 配置,可以控制倒排索引记录的内容
    • docs :记录 doc id
    • freqs :记录 doc id 和 term frequencies
    • positions :记录 doc id 、term frequencies 、 term position
    • offsets : 记录 doc id 、term frequencies 、 term position 、character offects
  • Text 类型默认记录 postions ,其他默认为 docs
  • 记录内容越多 ,占存储空间越大

null_value

有时候插入的某些字段值为 NULL ,但是又需要对 NULL 值进行搜索,可以使用 null_value,把 NULL 定义为一个指定的字符串,如 “NULL”

PUT users
{
  "mappings":{
    "properties":{
      "firstName":{
          "type":"text"
      },
      "lastName":{
      	"type":"text"
  	  },
  	"mobile":{
      "type":"keyword",  # 只有Keyword 类型支持设定 Null_value
      "null_value":"NULL"
      }
    }
  }
}

copy_to 设置

  • copy_to 将字段的值拷贝到目标字段
  • copy_to 的目标字段不出现在 _source 中
  • 用来满足一些特定的搜索需求
PUT users
{
  "mappings":{
    "properties":{
      "firstName":{
        "type":"text",
        "copy_to":"fullName"
      },
      "lastName":{
        "type":"text",
        "copy_to": "fullName"
      }
    }
  }
}
GET users/_search?q=fullName:(Z hl)

数组类型

ElasticSearch 中不提供专门的数组类型,但是任何字段,都可以包含多个相同类型的值

POST users/_doc
{
    "firstName":"Jack2",
    "lastName":"Jonson2"
}
POST users/_doc
{
    "firstName":["Jack2","jjj"],
    "lastName":"Jonson2"
}

多字段类型

  • 多字段特性
    • 增加一个 keyword 字段,实现字段名精确匹配
    • 使用不同的 analyzer
      • 不同的语言
      • 使用拼音对字段进行搜索
      • 还支持为搜索和索引指定不同的 analyzer
PUT products
{
  "mappings": {
    "properties": {
      "commpany": {
        "type": "text",
        "fields": {
          "keyword": {
            "type": "keyword",
            "ignore_above": 256 # 对超过256的字符串,analyzer不会进行处理
          }
        }
      },
      "comment": {
        "type": "text",
        "fields": {
          "english_comment": {
            "type": "text",
            "analyzer": "english",
            "search_analyzer": "english"
          }
        }
      }
    }
  }
}

精确值和全文本的比较

Exact Values v.s Full Text

  • Exact Values 精确值:包括 数字、日期、具体的字符串

    • ElasticSearch 里的 keyword 就是精确值

    • 精确值不需要被分词

  • Full Text 全文本,非结构化的文本数据

    ElasticSearch 里的 text 就是全文本

Index Template 和 Dynamic Template

什么是 Index Template

  • Index Templates : 帮你设定 Mappings 和 Settings,并按照一定的规则,自动匹配到新创建的索引之上
    • 模板仅在一个索引被新创建时,才会产生作用。修改模板不会影响已创建的索引
    • 你可以设定多个索引模块,这些设置会被 “merge” 在一起
    • 你可以指定 “order” 的数值,控制 “merging” 的过程
PUT _template/template_test
{
  "index_patterns": ["test*"],  # 作用在以test开头的索引
  "order":1,
  "settings": {
    "number_of_replicas": 1,
    "number_of_shards": 2
  },
  "mappings": {
    "date_detection": false,  # 关闭字符串自动转日期
    "numeric_detection": true # 开启字符串自动转数字
  }
}

Index Template 的工作方式

当一个索引被新创建时:

  • 应用 ElasticSearch 默认的 settings 和 mappings
  • 应用 order 数值低的 Index Template 中的设定
  • 应用 order 数值高的 Index Template 中的设定,会覆盖之前的设定
  • 应用用户创建时所指定的 Settings 和 Mappings ,并覆盖之前模板中的设定

什么是 Dynamic Template

Dynamic Template 是设定在一个具体的 index 上的,根据 ElasticSearch 识别的数据类型,结合字段名称,来动态设定字段类型,如:

  • 所有的字符串类型都设定成 Keyword ,或者关闭 keyword
  • is 开头的字段都设置成 boolean
  • long_ 开头的都设置成 long 类型
PUT my_test_index
{
  "mappings": {
    "dynamic_templates":[
      {
        "string_as_boolean":{
          "match_mapping_type":"string",
          "match":"is*",
          "mapping":{
            "type":"boolean"
          }
        }
      },
      {
        "string_as_keywords":{
          "match_mapping_type":"string",
          "mapping":{
            "type":"keyword"
          }
        }
      }
    ]
  }
}
  • Dynamic Template 是定义在某个索引的 Mappings中的
  • Template 有一个名称
  • 匹配规则是一个数组
  • 为匹配到字段设置 Mappings
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值