Elasticsearch系列---初識mapping

概要

本篇簡單介紹一下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的內容可以隨意輸入,當把這個作用工具調試時,可以診斷的內容的分詞情況,舉例如下:

  1. 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
    }
  ]
}
  1. 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架構社區
Java架構社區

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章