概要
本篇簡單介紹一下field數據類型mapping的相關知識。
mapping是什么?
前面幾篇的實戰案例,我們向Elasticsearch索引數據時,只是簡單地把JSON文本放在請求體里,至於JSON里的field類型,存儲到ES里是什么類型,中間是怎么做的映射,這個映射過程,就是mapping要解決的問題。
mapping簡單來說,就是解決JSON文本內容到field類型映射關系的定義。將時間域視為時間類型,數字視為數字類型,字符串識別為全文或精確值字符串,這個識別的過程,叫做mapping。
Elasticsearch支持的簡單域類型,類似於Java的基礎數據類型,有如下幾種:
- 字符串:text,keyword
- 整數 : byte, short, integer, long
- 浮點數: float, double
- 布爾型: boolean
- 日期: date
當Elasticsearch收到JSON基本數據類型內容時,使用如下規則進行類型映射:
JSON type | domain type |
---|---|
布爾型: true 或者 false | boolean |
整數: 123 | long |
浮點數: 123.45 | double |
日期格式的字符串: 2014-09-15 | date |
字符串: love you | text |
查看映射
每個索引都可以通過/_mapping查詢各個field的映射結果,ES本身有自動mapping的過程,但mapping后的結果一定要仔細檢查一下。
查詢請求:
GET /music/_mapping/children
響應結果:
{
"music": {
"mappings": {
"children": {
"properties": {
"content": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"language": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
},
"fielddata": true
},
"length": {
"type": "long"
},
"likes": {
"type": "long"
},
"name": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
}
}
}
}
mapping中就自動定義了每個field的數據類型,properties下面的是各個field字段的名稱、類型等信息,text類型的還帶一個keyword子field。
數據類型的分詞規則
index在建立時或索引數據時,如果沒有手動指定mapping信息,Elasticsearch會用它的規則自動為我們創建type信息,以及type對應的mapping,mapping中包含了每個field對應的數據類型,以及如何分詞等設置。
不同類型的field,有的是精確搜索(exact value),有的是全文搜索(full text)。
- exact value,在建立倒排索引的時候,是將整個值一起作為一個關鍵詞建立到倒排索引中的,並且大小寫敏感;
- full text,會經歷各種各樣的處理,分詞,normaliztion(時態轉換,同義詞轉換,大小寫轉換),才會建立到倒排索引中。
在一個搜索請求過來的時候,對exact value field和full text field進行搜索的會與當初建立倒排索引的行為保持一致;比如說exact value搜索的時候,就是直接按照整個值進行匹配,full text query string,也會進行分詞和normalization再去倒排索引中去搜索,這樣才能達到預期的搜索效果。
ES基本的幾種field類型,除了text是使用full text,其他的都是exact value,總結來說mapping,決定了數據類型,建立倒排索引的行為,還有進行搜索的行為。
自定義映射
基本數據類型基本夠用,但是有些數據可能需要自定義映射,尤其是字符串,string類型默認是full text,但是我們可以自己定義分詞器,不同的分詞器,會帶來不一樣的搜索效果,string類型最重要的屬性是index和analyzer。
index
這個屬性控制字符串的索引規則,有三個值可供選擇:
- true:支持索引,並且依據當前類型決定是全文搜索還是精確匹配
- false:不索引
例如:
{
"author": {
"type": "text",
"index": true
}
}
analyzer
這個屬性控制字符串使用的分詞器,在支持中文的系統里,這個屬性經常被用到,各路分詞器大顯身手,都需要用這個屬性來指定,如:
{
"content": {
"type": "text",
"analyzer": "aliws"
}
}
測試映射
我們在建立索引之后,可以通過測試命令來查看不同的field的映射結果,即full text類型的是否有分詞, exact value的是否原樣保留,text的內容可以隨意輸入,當把這個作用工具調試時,可以診斷的內容的分詞情況,舉例如下:
- full text類型
GET /music/_analyze
{
"field": "content",
"text": "let me sleep"
}
結果:
{
"tokens": [
{
"token": "let",
"start_offset": 0,
"end_offset": 3,
"type": "<ALPHANUM>",
"position": 0
},
{
"token": "me",
"start_offset": 4,
"end_offset": 6,
"type": "<ALPHANUM>",
"position": 1
},
{
"token": "sleep",
"start_offset": 7,
"end_offset": 12,
"type": "<ALPHANUM>",
"position": 2
}
]
}
- exact value類型
GET /music/_analyze
{
"field": "content.keyword",
"text": "let me sleep"
}
結果:
{
"tokens": [
{
"token": "let me sleep",
"start_offset": 0,
"end_offset": 12,
"type": "word",
"position": 0
}
]
}
注意一個小細節:Elasticsearch在自動創建text類型時,為full text,但會自動建立一個keywork子field,這個子field是exact value類型的。
小結
本篇主要介紹了一個mapping的概念,基礎數據類型,以及查看映射信息和測試field映射效果的方法,測試映射效果算是一個比較有用的工具,后期實際開發中,遇到需要診斷的內容,可以用這個工具協助排查問題。
專注Java高並發、分布式架構,更多技術干貨分享與心得,請關注公眾號:Java架構社區