ElasticSearch中 Dynamic Mapping 和 常见字段类型

什么是Mapping
  • Mapping 类似数据库中的 schema 的定义,作用如下
    1. 定义索引中的字段的名称
    2. 定义字段的数据类型, 例如 字符串,数字,布尔 。。。
    3. 字段,倒排索引的相关配置,(Analyzed or Not Analyzed Analyzer)
  • Mapping 会把 JSON 文件映射成 Lucene 所需要的扁平格式
  • 一个Mapping 属于一个索引的Type
    1. 每个文档都属于一个索引的Type
    2. 一个Type 有一个Mapping 定义
    3. 7.0 开始, 不需要在 Mapping 定义中指定 type 信息、
字段的数据类型
  • 简单类型
    1. Text / Keyword
    2. Date
    3. Integer / Floating
    4. Boolean
    5. Ipv4 & Ipv6
  • 复杂类型 - 对象和嵌套对象
    1. 对象类型 / 嵌套类型
  • 特殊类型
    1. geo_point & geo_shape / percolator
什么是 Dynamic Mapping
  • 在写入文档时候,如果索引不存在,会自动创建索引
  • Dynamic Mapping 的机制,使得我们无需手动定义 Mappings。ElasticSearch 会自动根据文档信息推算出字段的类型
  • 但是有时候会推算的不正确,例如 地理位置信息
  • 当类型如果设置不对时,会导致一些功能无法正常运行, 例如 Range 查询
尝试添加一个文档
// 写入文档,查看Mapping
PUT mapping_test/_doc/1
{
  "firstName": "Chan",
  "lastName" : "Jackie",
  "loginDate" : "2018-07-24T10:29:48.103Z"
}

查看mapping
// 查看Mapping 文件
GET mapping_test/_mapping
返回
{
  "mapping_test" : {
    "mappings" : {
      "properties" : {
        "firstName" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        },
        "lastName" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        },
        "loginDate" : {
          "type" : "date"
        }
      }
    }
  }
}

** 我们看到这里。es 将 loginDate 字符串自动处理成了 date 类型的**

重新添加一份
// dynamic mapping 推断字段的类型
PUT mapping_test/_doc/1
{
  "uid":"123",
  "isVip": false,
  "isAdmin":"true",
  "age":19,
  "heigh":180
}

查看 mapping

{
  "mapping_test" : {
    "mappings" : {
      "properties" : {
        "age" : {
          "type" : "long"
        },
        "heigh" : {
          "type" : "long"
        },
        "isAdmin" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        },
        "isVip" : {
          "type" : "boolean"
        },
        "uid" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        }
      }
    }
  }
}

我们看到ageheigh 都被处理为了long 类型, isVip 被处理为了 布尔类型,uId 被处理为了 text 类型,isAdmin 也被处理为了 text类型

ES 的类型自动识别
JSON类型ElasticSearch 类型
字符串匹配日期格式
字符串设置数字设置为float 或者long ,该选项默认关闭
字符串设置为Text,并且增加 keyword 子字段
布尔值boolean
浮点数float
整数long
对象Object
数组由第一个非空数值的类型所决定
空值忽略
能否修改Mapping的类型
两种情况
  1. 新增加字段
    • Dynamic 设置为true 时, 一旦有新增字段的文档写入, Mapping 也同时被更新
    • Dynamic 设置为false 时,Mapping 不会被更新,新增字段的数据无法被索引,但是信息会出现在_source 中
    • Dynamic 设置成Strict, 文档写入失败
  2. 对已有字段,一旦已经有数据写入,就不再支持修改字段定义
    • Lucene 实现的倒排索引, 必须Reindex API, 重建索引
    • 因为如果修改了字段的数据类型,会导致已被索引的属性无法被搜索,
    • 但是如果是增加新的字段,就不会有这样的影响。
truefalsestrict
文档可索引YESYESNO
字段可索引YESNONO
Mapping可以被更新YESNONO
控制 Dynamic Mappings
  • 当 dynamic 被设置为 false 的时候,存在新增字段的数据写入,该数据可以被索引。但是新增字段被丢弃
  • 当设置为 Strict 模式的时候,数据写入直接报错
PUT index_test
{
  "mappings": {
    "_doc":{
      "dynamic" : "false"
    }
  }
}
如何显示的定义一个Mapping
PUT movies
{
	"mappings" : {
		// defome your mappings here
	}
}
举个例子

Index - 控制当前字段是否被索引, 默认为 true ,如果设置为 false ,那么该字段就不可被搜索

// 显示的创建Mapping
PUT address_book
{
  "mappings": {
    "properties": {
      "name":{
        "type": "text"
      },
      "address":{
        "type": "text"
      },
      "phone_num":{
        "type": "text",
        "index": false
      }
    }
  }
}
  • 如果对 phone_num 进行搜索。那么将会报错
GET address_book/_search
{
  "query": {
    "match": {
      "phone": "151"
    }
  }
}

报错

{
  "error": {
    "root_cause": [
      {
        "type": "query_shard_exception",
        "reason": "failed to create query: {\n  \"match\" : {\n    \"phone\" : {\n      \"query\" : \"151\",\n      \"operator\" : \"OR\",\n      \"prefix_length\" : 0,\n      \"max_expansions\" : 50,\n      \"fuzzy_transpositions\" : true,\n      \"lenient\" : false,\n      \"zero_terms_query\" : \"NONE\",\n      \"auto_generate_synonyms_phrase_query\" : true,\n      \"boost\" : 1.0\n    }\n  }\n}",
        "index_uuid": "2DiCWC3-Q762F70ezJS7RQ",
        "index": "address_book"
      }
    ],
    "type": "search_phase_execution_exception",
    "reason": "all shards failed",
    "phase": "query",
    "grouped": true,
    "failed_shards": [
      {
        "shard": 0,
        "index": "address_book",
        "node": "oBuLww9BSBOBEg8MebGboA",
        "reason": {
          "type": "query_shard_exception",
          "reason": "failed to create query: {\n  \"match\" : {\n    \"phone\" : {\n      \"query\" : \"151\",\n      \"operator\" : \"OR\",\n      \"prefix_length\" : 0,\n      \"max_expansions\" : 50,\n      \"fuzzy_transpositions\" : true,\n      \"lenient\" : false,\n      \"zero_terms_query\" : \"NONE\",\n      \"auto_generate_synonyms_phrase_query\" : true,\n      \"boost\" : 1.0\n    }\n  }\n}",
          "index_uuid": "2DiCWC3-Q762F70ezJS7RQ",
          "index": "address_book",
          "caused_by": {
            "type": "illegal_argument_exception",
            "reason": "Cannot search on field [phone] since it is not indexed."
          }
        }
      }
    ]
  },
  "status": 400
}
  • 如果对name 进行搜索,那么手机号码还是会出现在_source 里面的
GET address_book/_search
{
  "query": {
    "match": {
      "name": "gaosongsong"
    }
  }
}

搜索结果

{
  "took" : 0,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 0.2876821,
    "hits" : [
      {
        "_index" : "address_book",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 0.2876821,
        "_source" : {
          "name" : "gaosongsong",
          "phone" : "15152268067"
        }
      }
    ]
  }
}

Index Options

在这里插入图片描述

  • 四种不同的级别的Index Options 设置,可以控制倒排索引记录的内容
    1. docs - 记录 doc id
    2. freqs - 记录 doc id 和 term frequencies
    3. positions - 记录 doc id 和 term frequencies / term position
    4. offsets - doc id / term frequencies / term position /character offects
  • Text 类型默认记录 positions,其他默认为 docs
  • 记录内容越多,占用存储空间越大
null_value
  • 需要对null 值进行搜索
  • 只有 KeyWord类型支持设定 null_Value

在这里插入图片描述

copy_to
  • _all 在 7 中被 copy_to 所替代
  • 满意一些特定的搜索要求
  • copy_to 将字段的数值拷贝到 目标字段, 实现类似 _all 的作用
  • copy_to 的目标字段不出现在 _source 中
    在这里插入图片描述
多字段类型
特性
  • 厂商名字实现精确匹配
    1. 增加一个 keyword 字段
  • 使用不同的 analyzer
    1. 不同语言
    2. pinyin 字段的搜索
    3. 还支持为搜索和索引指定不同的 analyzer

Exact Value(精确值) 不需要被分词 比如 Apple Store
ElsticSearch 中的 keyword
全文本,非结构化的文本数据, ElasticSearch 中的 text

  • ElasticSearch 为每一个字段创建一个倒排索引
    1. Exact Value 在索引时, 不需要做特殊的粉刺处理
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值