
創作人:歐陽楚才
映射(mapping)就像資料庫中的 Schema ,描述了文檔可能具有的字段或屬性、每個字段的資料類型,比如 text,keyword,integer 或 date ,以及 Lucene 是如何索引和存儲這些字段的。
核心簡單字段類型
Elasticsearch 支援如下簡單字段類型:
- 字元串: text,keyword
- 整數:byte,short,integer,long
- 浮點數: float,double
- 布爾型: boolean
- 日期: date
更多的字段類型比如 geo_point,ip,nested 等可以在連結處檢視: https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping-types.html
當你索引一個包含新字段的文檔之前,未曾出現 Elasticsearch 會使用動态映射,通過 JSON 中基本資料類型,嘗試猜測字段類型,使用如下規則:
JSON 資料 | 字段類型 |
---|---|
布爾型:true 或者 false | boolean |
整數:123 | long |
浮點數:123.45 | double |
字元串,有效日期:2021-05-01 | date |
字元串:foo bar | text 和 keyword |
注意:如果你通過引号 ( "123" ) 索引一個數字,它會被映射為字元串類型 text 和 keyword,而不是 long 。但如果這個字段已經映射為 long ,那麼 Elasticsearch 會嘗試将這個字元串轉化為 long (在 coerce 設定為 true 的情況下),如果無法轉化,則抛出一個異常。
檢視映射
通過 /_mapping ,我們可以檢視 Elasticsearch 在一個或多個索引中的映射。
Elasticsearch 文檔寫入示例:
PUT twitter/_doc/1
{
"user": "kimchy",
"post_date": "2009-11-15T13:12:00",
"message": "Trying out Elasticsearch, so far so good?"
}
PUT twitter/_doc/2
{
"user": "kimchy",
"post_date": "2009-11-15T14:12:12",
"message": "Another tweet, will it be indexed?"
}
PUT twitter/_doc/3
{
"user": "elastic",
"post_date": "2010-01-15T01:46:38",
"message": "Building the site, should be kewl"
}
檢視索引映射示例:
GET twitter/_mapping
Elasticsearch 根據我們索引的文檔,為字段動态生成的映射:
{
"twitter" : {
"mappings" : {
"properties" : {
"message" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
},
"post_date" : {
"type" : "date"
},
"user" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
}
}
}
}
}
注意:錯誤的映射,例如将年齡字段映射為 text 類型,而不是 integer ,會導緻查詢出現令人困惑的結果。
檢查一下,而不是假設你的映射是正确的。
自定義字段映射
盡管在很多情況下基本字段資料類型已經夠用,但你經常需要為單獨字段自定義映射,特别是字元串字段。自定義映射允許你執行下面的操作:
- 全文字元串字段和精确值字元串字段的差別
- 使用特定語言分析器
- 優化字段以适應部分比對
- 指定自定義資料格式
- 還有更多
字段最重要的屬性是 type 。
{
"number_of_clicks": {
"type": "integer"
}
}
字元串字段類型,包括全文字元串 text 和精确值字元串 keyword。
text 類型字段的最重要屬性是分析器 analyzer,預設 Elasticsearch 使用 Standard 分析器, 但你可以指定一個内置的分析器替代它,例如 whitespace 、 simple 、english、cjk:
{
"message": {
"type": "text",
"analyzer": "cjk"
}
}
建立/更新映射
當你首次建立一個索引的時候,可以指定類型的映射。你也可以使用 /_mapping 更新映射。
我們可以更新一個映射來添加一個新字段,但不能更新一個現有的 mapping 把它的字段類型從一個變為另外一個,比如從 text 變為 keyword。我
們可以在維持現有 mapping 的情況下,把一個字段變成一個 multi-field 字段。
為了描述指定映射的兩種方式,我們先删除 twitter 索引:
DELETE twitter
建立一個新索引,指定 message 字段使用 cjk 分析器:
PUT twitter
{
"settings": {
"number_of_shards": "5",
"number_of_replicas": "1"
},
"mappings": {
"properties": {
"user": {
"type": "keyword"
},
"post_date": {
"type": "date"
},
"message": {
"type": "text",
"analyzer": "cjk"
}
}
}
}
通過消息體中指定的 mappings 建立了索引映射,索引設定 settings 中通過 number_of_shards 指定分片數,number_of_replicas 指定副本數。
給映射增加一個新的名為 tag 的 keyword 類型字段,使用 _mapping :
PUT twitter/_mapping
{
"properties": {
"tag": {
"type": "keyword"
}
}
}
我們不需要再次列出所有已存在的字段,因為無論如何我們都無法改變它們,新字段已經被合并到存在的映射中。
測試映射
可以使用 analyze API 測試字元串字段的映射,比較下面兩個請求的輸出:
GET /twitter/_analyze
{
"field": "message",
"text": "搜尋引擎"
}
GET /twitter/_analyze
{
"field": "tag",
"text": "搜尋引擎"
}
消息體裡面傳入我們想要分析的文本。message 字段産生 3 個詞條 ”搜尋“、”索引” 和 ”引擎“, tag 字段産生單獨的詞條”搜尋引擎“,換句話說,我們的映射正常工作。