ElasticSearch(五):Mapping和常見字段類型


ElasticSearch(五):Mapping和常見字段類型

學習課程鏈接《Elasticsearch核心技術與實戰》


## 什么是Mapping * Mapping類似數據庫中的schema的定義,作用如下: - 定義索引中的字段的名稱; - 定義字段的數據類型,例如字符串、數字、日期、布爾等; - 對每個字段進行倒排索引的相關配置(Analyzed or Not Analyzed,Analyzer); * Mapping 會把JSON文旦映射成Lucene所需要的扁平格式。 * 一個Mapping屬於一個索引的Type: - 每個文檔都屬於一個Type; - 一個Tpye有一個Mapping定義; - 7.0開始,不需要再Mapping定義中指定type信息;
## 字段的數據類型 * 簡單類型 - Text - Date - Integer/Long/Floating - Boolean - IP4&IP6 - Keyword * 復雜類型 - 對象類型 - 嵌套類型 * 特殊類型(地理信息) - geo_point&geo_shape、percolator
## 什么是Dynamic Mapping * 在寫入文檔的時候,如果索引不存在,則會自動創建索引; * Dynamic Mapping機制,可以無需手動定義Mapping,ElasticSearch會自動根據文檔信息,推算出字段的類型; * 但是有時候推算的可能不對,例如地理位置信息; * 當類型設置的不對時,會導致一些功能無法正常運行,比如范圍內的Range查詢;
## 類型的自動識別 JSON類型|Elasticsearch類型 ---|--- 字符串|匹配日期格式,設置成Date;匹配數字設置成Float或者Long,該選項默認關閉;設置為Text,並且增加keyword子字段 布爾值|Boolean 浮點數|Float 整數|Long 對象|Object 數組|由第一個非空數的類型所決定 空值|忽略
``` #寫入文檔,查看 Mapping PUT mapping_test/_doc/1 { "firstName":"Chan", "loginDate":"2018-07-24T10:29:48.103Z", "uid" : "123", "isVip" : false, "isAdmin": "true", "age":19, "heigh":180 }

Delete index

DELETE mapping_test

查看 Dynamic Mapping文件

GET mapping_test/_mapping


查看 Dynamic Mapping返回結果

{
"mapping_test" : {
"mappings" : {
"properties" : {
"age" : {
"type" : "long" # "age":19,設置為long
},
"firstName" : {
"type" : "text", # "firstName":"Chan",設置為Text,並且增加keyword子字段
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
},
"heigh" : {
"type" : "long" #"heigh":180設置為long
},
"isAdmin" : {
"type" : "text", #"isAdmin": "true",設置為Text,並且增加keyword子字段
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
},
"isVip" : {
"type" : "boolean" #"isVip" : false,設置為boolean
},
"loginDate" : {
"type" : "date" #"loginDate":"2018-07-24T10:29:48.103Z",設置為Date
},
"uid" : {
"type" : "text", # "uid" : "123",設置為Text,並且增加keyword子字段,匹配數字設置成Float或者Long,該選項默認關閉;
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
}
}
}
}
}




<br/>
## 能否更改 Mapping 的字段類型
分兩種情況:
* 新增加字段
  - Dynamic設置為true時,一旦有新增字段的文檔寫入,Mapping也同時被更新;
  - Dynamic設置為false時,Mapping不會被更新,新增字段的數據無法被索引,但是信息會出現在_source中;
  - Dynamic設置為strict時,文檔寫入失敗;
* 對已有字段,一旦已有數據寫入,就不在支持修改字段定義
  - Lucene實現的倒排索引,一旦生成后,就不允許修改
  - 如果希望修改字段類型,必須Reindex API,重建索引
  - 如果修改了字段的數據類型,會導致已被索引的數據無法被搜索
  


<br/>
## 控制Dynamic Mappings
dynamic|true|false|strict
---|---|---|---
文檔可索引|YES|YES|NO
字段可索引|YES|NO|NO
Mapping被更新|YES|NO|NO
<br/>
* 當dynamic被設置成false時,存在新增字段數據寫入,該數據可以被索引,但新增字段被丟棄
* 當dynamic被設置成strict時,數據寫入直接出錯

1.默認Mapping支持dynamic,寫入的文檔中加入新的字段

PUT dynamic_mapping_test/_doc/1
{
"newField":"someValue"
}


2.該字段可以被搜索,數據也在_source中出現

POST dynamic_mapping_test/_search
{
"query":{
"match":{
"newField":"someValue"
}
}
}

返回結果:

{
"took" : 5,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max_score" : 0.2876821,
"hits" : [
{
"_index" : "dynamic_mapping_test",
"_type" : "_doc",
"_id" : "1",
"_score" : 0.2876821,
"_source" : {
"newField" : "someValue"
}
}
]
}
}


3.修改為dynamic false

PUT dynamic_mapping_test/_mapping
{
"dynamic": false
}


4.新增 anotherField

PUT dynamic_mapping_test/_doc/10
{
"anotherField":"someValue"
}


5.該字段不可以被搜索,因為dynamic已經被設置為false

POST dynamic_mapping_test/_search
{
"query":{
"match":{
"anotherField":"someValue"
}
}
}

返回結果:

{
"took" : 657,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 0,
"relation" : "eq"
},
"max_score" : null,
"hits" : [ ]
}
}


6.修改為strict

PUT dynamic_mapping_test/_mapping
{
"dynamic": "strict"
}


7.寫入數據出錯,HTTP Code 400

PUT dynamic_mapping_test/_doc/12
{
"lastField":"value"
}

返回結果:

{
"error": {
"root_cause": [
{
"type": "strict_dynamic_mapping_exception",
"reason": "mapping set to strict, dynamic introduction of [lastField] within [_doc] is not allowed"
}
],
"type": "strict_dynamic_mapping_exception",
"reason": "mapping set to strict, dynamic introduction of [lastField] within [_doc] is not allowed"
},
"status": 400
}




<br/>
## 如何定義一個 Mapping

PUT index_name
{
"mappings":{
"properties":{
//define your mappings here
}
}
}


* 可以參考API手冊,純手寫;
* 為了減少輸入的工作量,減少出錯概率,可以依照以下步驟:
  - 創建一個臨時的index,寫入一些樣本數據;
  - 通過訪問Mapping API獲取該臨時文件的動態Mapping定義;
  - 修改后,使用該配置創建你的索引
  - 刪除臨時索引
  
	
<br/>
## Mapping的一些配置
* ` index`控制當前字段是否被索引,默認為`true`。如果設置成`false`,該字段不可被搜索。
* `index_options`可以控制倒排索引記錄的內容,有四種不同級別的配置:
  - `docs`記錄 doc id
  - `freqs`記錄 doc id / term frequencies
  - `positions`記錄  doc id / term frequencies / term position
  - `offects`記錄  doc id / term frequencies / term position / character offects 
* Text類型默認記錄`positions`,其他默認為 `docs`。記錄的類容越多,占用存儲空間越大。
* ` null_value`控制需要對Null值實現搜索;只有Keyword類型支持設定null_value。
* ` copy_to`滿足一些特定的搜索需求,` copy_to`將字段的數值拷貝到目標字段,實現類似`_all`的作用,`_all`在ES7中被` copy_to`所替代,` copy_to`的目標字段不出現在_source中。
*  Elasticsearch中不提供專門的數組類型。但是任何字段,都可以包含多個相同類類型的數值。

1.設置 index 為 false

DELETE users
PUT users
{
"mappings" : {
"properties" : {
"firstName" : {
"type" : "text"
},
"lastName" : {
"type" : "text"
},
"mobile" : {
"type" : "text",
"index": false
}
}
}
}

插入數據

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: {\n "match" : {\n "mobile" : {\n "query" : "12345678",\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": "1oB9dwY2TPq-9QjiaMaU7g",
"index": "users"
}
],
"type": "search_phase_execution_exception",
"reason": "all shards failed",
"phase": "query",
"grouped": true,
"failed_shards": [
{
"shard": 0,
"index": "users",
"node": "u-4S1mfbQiuA1Bqe-wfPJQ",
"reason": {
"type": "query_shard_exception",
"reason": "failed to create query: {\n "match" : {\n "mobile" : {\n "query" : "12345678",\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": "1oB9dwY2TPq-9QjiaMaU7g",
"index": "users",
"caused_by": {
"type": "illegal_argument_exception",
"reason": "Cannot search on field [mobile] since it is not indexed." #錯誤原因
}
}
}
]
},
"status": 400
}


設定Null_value

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

  }
}

}

插入數據

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"
}
}
}

查詢返回結果:

{
"took" : 1,
"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
}
}
]
}
}

設置 Copy to

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"
}

查詢方法1

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

查詢方法2

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

查詢返回結果:

{
"took" : 1,
"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"
}
}
]
}
}


數組類型

PUT users/_doc/1
{
"name":"twobirds",
"interests":["reading","music"]
}
GET users/_mapping

返回Mapping結果:

{
"users" : {
"mappings" : {
"properties" : {
"firstName" : {
"type" : "text",
"copy_to" : [
"fullName"
]
},
"fullName" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
},
"interests" : {
"type" : "text", #數組類型,根據數組里數據類型配置
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
},
"lastName" : {
"type" : "text",
"copy_to" : [
"fullName"
]
},
"name" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
}
}
}
}
}



<br/>


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM