7.Mapping详解

1.什么是Mapping

1.Mapping 类似数据库中的schema的定义,作用如下

  • 定义索引中的字段的名称
  • 定义字段的数据类型,例如字符串,数字,布尔…
  • 字段,倒排索引的相关配置(Analyzed or Not Analyzed,Analyzer)

2.Mapping会把JSON文档映射成Lucene所需要的扁平格式
3.一个Mapping属于一个索引的Type

  • 每个文档都属于一个Type
  • 一个Type有一个Mapping定义
  • 7.0开始不需要在Mapping定义中指定type信息

1.1 字段的数据类型

  • 简单类型
    • Text/Keyword
    • Date
    • Integer/Floating
    • Boolean
    • IPv4 & IPv6
  • 复杂类型-对象和嵌套对象
    • 对象类型/嵌套类型
  • 特殊类型
    • geo_point & geo_shape / percolator

2 什么是Dynamic Mapping

  • 在写入文档时候,如果索引不存在,会自动创建索引

  • Dynamic Mapping的机制,使得我们无需手动定义Mappings. Elasticsearch 会自动根据文档信息,推算出字段的类型

  • 但是有时候会推算的不对,例如地理位置信息推算成text

  • 当类型如果设置不对时,会导致一些功能无法正常运行,例如Range查询

      //写入文档,查看 Mapping
      PUT mapping_test/_doc/1
      {
        "firstName":"Chan",
        "lastName": "Jackie",
        "loginDate":"2018-07-24T10:29:48.103Z"
      }
      // 查看mapping	
      GET mapping_test/_mapping
      // 返回结果
      {
        "mapping_test" : {
          "mappings" : {
            "properties" : {
              "firstName" : {
                "type" : "text",   // 类型 每一个 text 都有 keyword
                "fields" : {
                  "keyword" : {
                    "type" : "keyword",
                    "ignore_above" : 256
                  }
                }
              },
              "lastName" : {
                "type" : "text", 	//类型
                "fields" : {
                  "keyword" : {
                    "type" : "keyword",
                    "ignore_above" : 256
                  }
                }
              },
              "loginDate" : {
                "type" : "date"		//日期类型
              }
            }
          }
        }
      }
      DELETE mapping_test
    

2.1 类型的自动识别

JSON类型Elasticsearch类型
字符串匹配日期格式,设置成Date
字符串配置数字设置为float或者long,该选项默认关闭
字符串设置为Text ,并且增加keyword子字段
布尔值boolean
浮点数float
整数long
对象Object
数组由第一个非空数值的类型所决定
空值忽略
//dynamic mapping,推断字段的类型
PUT mapping_test/_doc/1
{
    "uid" : "123",
    "isVip" : false,
    "isAdmin": "true",
    "age":19,
    "heigh":180
}
GET mapping_test/_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
            }
          }
        }
      }
    }
  }
}

2.2 能否更改Mapping的字段类型

两种情况

  • 新增加字段
    • Dynamic 设为true时,一旦有新增字段的文档写入,Mapping也同时被更新
    • Dynamic 设为false,Mapping不会被更新,新增字段的数据无法被索引
    • Dynamic 设置成Strict ,文档写入失败
  • 对已有字段,一旦已经有数据写入,就不再支持修改字段定义
    • Lucene 实现的倒排索引,一旦生成后,就不允许修改
  • 如果希望改变字段类型,必须 Reindex API 重建索引
  • 如果修改了字段的数据类型,会导致已被索引的属于无法被搜索
  • 但是如果是增加了新的字段,就不会有这样的影响

2.3 控制Dynamic Mappings

在这里插入图片描述

  • 当dynamic 被设置成false时候,存在新增字段的数据写入,该数据可以被索引,但是新增字段被丢弃

  • 当设置成Strict模式时候,数据直接写入直接出错

      	//默认Mapping支持dynamic,写入的文档中加入新的字段
      PUT dynamic_mapping_test/_doc/1
      {
        "newField":"someValue"
      }
      
      //该字段可以被搜索,数据也在_source中出现
      POST dynamic_mapping_test/_search
      {
        "query":{
          "match":{
            "newField":"someValue"
          }
        }
      }
      
      
      //修改为dynamic false
      PUT dynamic_mapping_test/_mapping
      {
        "dynamic": false
      }
      
      //新增 anotherField
      PUT dynamic_mapping_test/_doc/10
      {
        "anotherField":"someValue"
      }
      
      
      //该字段不可以被搜索,应为dynamic已经被设置为false
      POST dynamic_mapping_test/_search
      {
        "query":{
          "match":{
            "anotherField":"someValue"
          }
        }
      }
      
      get dynamic_mapping_test/_doc/10
      
      //修改为strict
      PUT dynamic_mapping_test/_mapping
      {
        "dynamic": "strict"
      }
      
      
      
      //写入数据出错,HTTP Code 400
      PUT dynamic_mapping_test/_doc/12
      {
        "lastField":"value"
      }
      
      DELETE dynamic_mapping_test
    

3 显示定义一个Mapping

一些建议
在这里插入图片描述

3.1 Index

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

设置索引

PUT users
{
    "mappings" : {
      "properties" : {
        "firstName" : {
          "type" : "text"
        },
        "lastName" : {
          "type" : "text"
        },
        "mobile" : {
          "type" : "text",
          "index": false  // 设置mobile 字段不可被索引
        }
      }
    }
}

插入数据

	PUT users/_doc/1
{
  "firstName":"Ruan",
  "lastName": "Yiming",
  "mobile": "12345678"
}

搜索字段

	POST /users/_search
{
  "query": {
    "match": {
      "mobile":"12345678"
    }
  }
}

返回结果

	"error": {
    "root_cause": [
      {
        "type": "query_shard_exception",
        "reason": "failed to create query: 
3.2 Index Options
  • 四种不同级别的Index Options 配置,可以控制倒排索引记录的内容
    • docs --记录 doc id
    • freqs – 记录 doc id , term frequencies
    • posititions --记录 doc id ,term frequencies, term position
    • offsets --记录 doc id,term frequencies,term posistion,character offects
  • Text 类型默认记录 positions,其他默认为docs
  • 记录内容越多,占用空间越大

定义mapping

	PUT my_index
		{
		  "mappings": {
		    "properties": {
		      "text": {
		        "type": "text",
		        "index_options": "offsets"
		      }
		    }
		  }
		}

插入数据

	PUT /my_index/_doc/1
	{
	  "text": "Quick brown fox"
	}

search

	GET /my_index/_search'
	{
	  "query": {
	    "match": {
	      "text": "brown fox"
	    }
	  },
	  "highlight": {
	    "fields": {
	      "text": {} 
	    }
	  }
	}
3.3 null_value

一个字段是null值则不能被索引或搜索。当字段设置为null(或空数组)时,它被视为该字段没有值。
null_value参数允许您使用指定的值替换null,以便可以对其进行索引和搜索

定义mapping

DELETE users
PUT users
{
    "mappings" : {
      "properties" : {
        "firstName" : {
          "type" : "text"
        },
        "lastName" : {
          "type" : "text"
        },
        "mobile" : {
          "type" : "keyword",
          "null_value": "NULL_test"
        }

      }
    }
}

插入值

PUT users/_doc/1
{
  "firstName":"Ruan",
  "lastName": "Yiming",
  "mobile": null
}
PUT users/_doc/2
{
  "firstName":"Ruan2",
  "lastName": "Yiming2"

搜索

}
GET users/_search
{
  "query": {
    "match": {
      "mobile":"NULL_test"
    }
  }
}

返回值

	{
  "took" : 25,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 0.2876821,
    "hits" : [
      {
        "_index" : "users",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 0.2876821,
        "_source" : {
          "firstName" : "Ruan",
          "lastName" : "Yiming",
          "mobile" : null   // 可以被索引  但是id=2的没有不能被搜索到
        }
      }
    ]
  }
}
3.4 copy_to

copy_to将字段的数值拷贝到目标字段,实现类似 _all的作用
copy_to的目标字段不出现在_source中,可以满足一些特定的搜索需求

定义mapping

DELETE users
PUT users
{
  "mappings": {
    "properties": {
      "firstName":{
        "type": "text",
        "copy_to": "fullName"
      },
      "lastName":{
        "type": "text",
        "copy_to": "fullName"
      }
    }
  }
}

插入值

	PUT users/_doc/1
{
  "firstName":"Ruan",
  "lastName": "Yiming"
}

搜索

GET users/_search?q=fullName:(Ruan Yiming)

POST users/_search
{
  "query": {
    "match": {
       "fullName":{
        "query": "Ruan Yiming",
        "operator": "and"
      }
    }
  }
}

返回结果

	{
  "took" : 16,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 0.5753642,
    "hits" : [
      {
        "_index" : "users",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 0.5753642,
        "_source" : {
          "firstName" : "Ruan",
          "lastName" : "Yiming"
        }
      }
    ]
  }
}

更多的参数请参考
Elasticsearch

4 数组类型

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

//数组类型

PUT users/_doc/1
{
  "name":"onebird",
  "interests":"reading"
}

PUT users/_doc/1
{
  "name":"twobirds",
  "interests":["reading","music"]
}
POST users/_search
{
  "query": {
		"match_all": {}
	}
}
GET users/_mapping
  • 2
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值