Elasticsearch 字段類型

在學習 ES 文檔相關操作之前,我們先學習 ES 中常用的字段類型。

1、text

當一個字段的內容需要被全文檢索時,可以使用text類型,支持長內容的存儲,比如檢索文章內容、商品信息等。該類型的字段內容會被分詞器分析,並且拆分成多個詞項, 然後根據拆分後的詞項生成對應的倒排索引,所以對於text類型的字段你可能無法通過指定文本精確的檢索到,因爲指定的文本可能也被分詞了。另外需要注意的是,text類型的字段不能直接用於排序、聚合操作。這種類型的字符串也稱做analyzed字符串。

2、keyword

keyword類型適用於結構化的字段,比如手機號、商品id、用戶id等,默認最大長度爲256。keyword類型的字段內容不會被分詞器分析、拆分,而是根據原始文本直接生成倒排索引,所以keyword類型的字段可以直接通過原始文本精確的檢索到。keyword類型的字段可用於過濾、排序、聚合操作。這種字符串稱做not-analyzed字符串。

3、日期類型

ES 中的date類型默認支持如下兩種格式:

  • strict_date_optional_time,表示 yyyy-MM-dd'T'HH:mm:ss.SSSSSSZ 或者 yyyy-MM-dd 格式的日期
  • epoch_millis,表示從 1970.1.1 零點到現在的毫秒數,

如果我們要存儲類似2020-12-01 20:10:15這種格式的日期就會有問題,我們可以在創建索引時指定字段爲date類型以及可以匹配的日期格式:

PUT blog
{
  "mappings": {
    "properties": {
      "publishDate":{
        "type": "date",
        "format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
      }
    }
  }
}

需要注意的是,如果不主動指定字段類型爲date,ES 默認使用text類型去保存日期的值。

4、布爾類型

boolean類型就簡單了,有truefalse兩個值。

5、數值類型

類型 取值範圍
byte -2^7 ~ 2^7-1
short -2^15 ~ 2^15-1
integer -2^31 ~ 2^31-1
long -2^63 ~ 2^63-1
float 32位單精度IEEE 754浮點類型
double 64位雙精度IEEE 754浮點類型
half_float 16位半精度IEEE 754浮點類型
scaled_float 縮放類型的的浮點數

一般情況下,如果可以滿足需求,則優先使用範圍小的類型,來提高效率。

6、數組類型

其實在 ES 中並沒有數組類型,但我們卻可以按數組格式來存儲數據,因爲 ES 中默認每個字段可以包含多個值,同時要求多個值得類型必須一致。例如可以按照如下方式指定一個字段的值爲數組:

"label": [
    "Elastcsearch",
    "7.9.3版本"
  ]

7、對象類型

這個其實沒什麼特別的,由於 ES 中以 JSON 格式存儲數據,所以一個 JSON 對象中的某個字段值可以是另一個 JSON 對象。

8、範圍類型

類型 技能
integer_range -2^31 ~ 2^31-1
long_range -2^63 ~ 2^63-1
float_range 32位單精度IEEE 754浮點類型
double_range 64位雙精度IEEE 754浮點類型
date_range 自系統曆元以來無符號64位整數範圍內的毫秒數
ip_range IPv4、IPv6 的一系列IP地址值

例如我們可以創建索引時定義一個日期範圍的字段類型:

PUT blog
{
  "mappings": {
    "properties": {
      "reader_age_range":{
        "type": "integer_range"
      }
    }
  }
}

添加文檔時可以這樣指定字段的值:

"reader_age_range": {
    "gte": 10,
    "lte": 50
}



最後我們通過一個完整的例子梳理一下這些字段類型,首先創建blog索引,並指定相關字段的類型:

PUT blog
{
  "mappings": {
    "properties": {
      "publishDate": {
        "type": "date",
        "format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
      },
      "reader_age_range": {
        "type": "integer_range"
      }
    }
  }
}

然後添加一條文檔數據:

POST blog/_doc
{
  "title": "Learn Elastcsearch",
  "publishDate": "2020-12-01 20:10:15",
  "isTop": true,
  "score": 4.5,
  "commnetNum": 50,
  "label": [
    "Elastcsearch",
    "7.9.3版本"
  ],
  "author": {
    "name": "shehuan",
    "github": "https://github.com/shehuan"
  },
  "reader_age_range": {
    "gte": 10,
    "lte": 50
  }
}

上邊我們只指定了publishDatereader_age_range字段的類型,其它的並未指定。其實在添加文檔時,ES 也會根據字段的值動態的推斷出它的類型,即動態映射,但這樣可能出現推斷不符合預期的問題,例如前邊說過的日期類型,所以你可以根據實際情況選擇是否主動指定字段的類型。

再使用如下請求查看一下文檔字段的mapping信息:

GET blog/_mapping?pretty

結果如下:

{
  "blog" : {
    "mappings" : {
      "properties" : {
        "author" : {
          "properties" : {
            "github" : {
              "type" : "text",
              "fields" : {
                "keyword" : {
                  "type" : "keyword",
                  "ignore_above" : 256
                }
              }
            },
            "name" : {
              "type" : "text",
              "fields" : {
                "keyword" : {
                  "type" : "keyword",
                  "ignore_above" : 256
                }
              }
            }
          }
        },
        "commnetNum" : {
          "type" : "long"
        },
        "isTop" : {
          "type" : "boolean"
        },
        "label" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        },
        "publishDate" : {
          "type" : "date",
          "format" : "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
        },
        "reader_age_range" : {
          "type" : "integer_range"
        },
        "score" : {
          "type" : "float"
        },
        "title" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        }
      }
    }
  }
}

由於我們未指定title字段的類型, ES 自動將其映射成了text類型,同時還添加了一個類型爲keyword的字段:


這意味着,我們可以使用title.keyword的方式將title字段當做keyword類型去使用。

ES 中常用的字段類型就介紹到這裏了。其中textkeyword可能理解起來比較抽象,後邊結合具體的例子就好理解了,分詞相關的內容後邊也會專門介紹。

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