ES 15 - Elasticsearch中的數據類型 (text、keyword、date、geo等)

来源:https://www.cnblogs.com/shoufeng/archive/2019/04/11/10692113.html
-Advertisement-
Play Games

Elasticsearch中每個field都對應一個數據類型. 本篇詳細介紹string、date、array、object、nested、geo等數據類型的作用及主要用法. 歡迎交流( ⊙ o ⊙ ) ...


目錄

說在前面: Elasticsearch中每個field都要精確對應一個數據類型.
本文的所有演示, 都是基於Elasticsearch 6.6.10進行的, 不同的版本可能存在API發生修改、不支持的情況, 還請註意.

1 核心數據類型

1.1 字元串類型 - string(不再支持)

(1) 使用示例:

PUT website
{
    "mappings": {
        "blog": {
            "properties": {
                "title": {"type": "string"},    // 全文本
                "tags": {"type": "string", "index": "not_analyzed"} // 關鍵字, 不分詞
            }
        }
    }
}

(2) ES 5.6.10中的響應信息:

#! Deprecation: The [string] field is deprecated, please use [text] or [keyword] instead on [tags]
#! Deprecation: The [string] field is deprecated, please use [text] or [keyword] instead on [title]
{
  "acknowledged": true,
  "shards_acknowledged": true,
  "index": "website"
}

(3) ES 6.6.10中的響應信息:

{
  "error": {
    "root_cause": [
      {
        "type": "mapper_parsing_exception",
        "reason": "No handler for type [string] declared on field [title]"
      }
    ],
    "type": "mapper_parsing_exception",
    "reason": "Failed to parse mapping [blog]: No handler for type [string] declared on field [title]",
    "caused_by": {
      "type": "mapper_parsing_exception",
      "reason": "No handler for type [string] declared on field [title]"
    }
  },
  "status": 400
}

可知string類型的field已經被移除了, 我們需要用text或keyword類型來代替string.

1.1.1 文本類型 - text

在Elasticsearch 5.4 版本開始, text取代了需要分詞的string.

—— 當一個欄位需要用於全文搜索(會被分詞), 比如產品名稱、產品描述信息, 就應該使用text類型.

text的內容會被分詞, 可以設置是否需要存儲: "index": "true|false".
text類型的欄位不能用於排序, 也很少用於聚合.

使用示例:

PUT website
{
    "mappings": {
        "blog": {
            "properties": {
                "summary": {"type": "text", "index": "true"}
            }
        }
    }
}

1.1.2 關鍵字類型 - keyword

在Elasticsearch 5.4 版本開始, keyword取代了不需要分詞的string.

—— 當一個欄位需要按照精確值進行過濾、排序、聚合等操作時, 就應該使用keyword類型.

keyword的內容不會被分詞, 可以設置是否需要存儲: "index": "true|false".

使用示例:

PUT website
{
    "mappings": {
        "blog": {
            "properties": {
                "tags": {"type": "keyword", "index": "true"}
            }
        }
    }
}

1.2 數字類型 - 8種

數字類型有如下分類:

類型 說明
byte 有符號的8位整數, 範圍: [-128 ~ 127]
short 有符號的16位整數, 範圍: [-32768 ~ 32767]
integer 有符號的32位整數, 範圍: [$-2^{31}$ ~ $2^{31}$-1]
long 有符號的32位整數, 範圍: [$-2^{63}$ ~ $2^{63}$-1]
float 32位單精度浮點數
double 64位雙精度浮點數
half_float 16位半精度IEEE 754浮點類型
scaled_float 縮放類型的的浮點數, 比如price欄位只需精確到分, 57.34縮放因數為100, 存儲結果為5734

使用註意事項:

儘可能選擇範圍小的數據類型, 欄位的長度越短, 索引和搜索的效率越高;
優先考慮使用帶縮放因數的浮點類型.

使用示例:

PUT shop
{
    "mappings": {
        "book": {
            "properties": {
                "name": {"type": "text"},
                "quantity": {"type": "integer"},  // integer類型
                "price": {
                    "type": "scaled_float",       // scaled_float類型
                    "scaling_factor": 100
                }
            }
        }
    }
}

1.3 日期類型 - date

JSON沒有日期數據類型, 所以在ES中, 日期可以是:

  • 包含格式化日期的字元串, "2018-10-01", 或"2018/10/01 12:10:30".
  • 代表時間毫秒數的長整型數字.
  • 代表時間秒數的整數.

如果時區未指定, 日期將被轉換為UTC格式, 但存儲的卻是長整型的毫秒值.
可以自定義日期格式, 若未指定, 則使用預設格式: strict_date_optional_time||epoch_millis

(1) 使用日期格式示例:

// 添加映射
PUT website
{
    "mappings": {
        "blog": {
            "properties": {
                "pub_date": {"type": "date"}   // 日期類型
            }
        }
    }
}

// 添加數據
PUT website/blog/11
{ "pub_date": "2018-10-10" }

PUT website/blog/12
{ "pub_date": "2018-10-10T12:00:00Z" }  // Solr中預設使用的日期格式

PUT website/blog/13
{ "pub_date": "1589584930103" }         // 時間的毫秒值

(2) 多種日期格式:

多個格式使用雙豎線||分隔, 每個格式都會被依次嘗試, 直到找到匹配的.
第一個格式用於將時間毫秒值轉換為對應格式的字元串.

使用示例:

// 添加映射
PUT website
{
    "mappings": {
        "blog": {
            "properties": {
                "date": {
                    "type": "date",  // 可以接受如下類型的格式
                    "format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
                }
            }
        }
    }
}

1.4 布爾類型 - boolean

可以接受表示真、假的字元串或數字:

  • 真值: true, "true", "on", "yes", "1"...
  • 假值: false, "false", "off", "no", "0", ""(空字元串), 0.0, 0

1.5 二進位型 - binary

二進位類型是Base64編碼字元串的二進位值, 不以預設的方式存儲, 且不能被搜索.

使用示例:

// 添加映射
PUT website
{
    "mappings": {
        "blog": {
            "properties": {
                "blob": {"type": "binary"}   // 二進位
            }
        }
    }
}
// 添加數據
PUT website/blog/1
{
    "title": "Some binary blog",
    "blob": "hED903KSrA084fRiD5JLgY=="
}

註意: Base64編碼的二進位值不能嵌入換行符\n.

1.6 範圍類型 - range

range類型支持以下幾種:

類型 範圍
integer_range $-2^{31}$ ~ $2^{31}-1$
long_range $-2^{63}$ ~ $2^{63}-1$
float_range 32位單精度浮點型
double_range 64位雙精度浮點型
date_range 64位整數, 毫秒計時
ip_range IP值的範圍, 支持IPV4和IPV6, 或者這兩種同時存在

(1) 添加映射:

PUT company
{
    "mappings": {
        "department": {
            "properties": {
                "expected_number": {  // 預期員工數
                    "type": "integer_range"
                },
                "time_frame": {       // 發展時間線
                    "type": "date_range", 
                    "format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
                },
                "ip_whitelist": {     // ip白名單
                    "type": "ip_range"
                }
            }
        }
    }
}

(2) 添加數據:

PUT company/department/1
{
    "expected_number" : {
        "gte" : 10,
        "lte" : 20
    },
    "time_frame" : { 
        "gte" : "2018-10-01 12:00:00", 
        "lte" : "2018-11-01"
    }, 
    "ip_whitelist": "192.168.0.0/16"
}

(3) 查詢數據:

GET company/department/_search
{
    "query": {
        "term": {
            "expected_number": {
                "value": 12
            }
        }
    }
}
GET company/department/_search
{
    "query": {
        "range": {
            "time_frame": {
                "gte": "208-08-01",
                "lte": "2018-12-01",
                "relation": "within" 
            }
        }
    }
}

查詢結果:

{
  "took": 26,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 1,
    "max_score": 1.0,
    "hits": [
      {
        "_index": "company",
        "_type": "department",
        "_id": "1",
        "_score": 1.0,
        "_source": {
          "expected_number": {
            "gte": 10,
            "lte": 20
          },
          "time_frame": {
            "gte": "2018-10-01 12:00:00",
            "lte": "2018-11-01"
          },
          "ip_whitelist" : "192.168.0.0/16"
        }
      }
    ]
  }
}

2 複雜數據類型

2.1 數組類型 - array

ES中沒有專門的數組類型, 直接使用[]定義即可;

數組中所有的值必須是同一種數據類型, 不支持混合數據類型的數組:

① 字元串數組: ["one", "two"];
② 整數數組: [1, 2];
③ 由數組組成的數組: [1, [2, 3]], 等價於[1, 2, 3];
④ 對象數組: [{"name": "Tom", "age": 20}, {"name": "Jerry", "age": 18}].

註意:

  • 動態添加數據時, 數組中第一個值的類型決定整個數組的類型;
  • 不支持混合數組類型, 比如[1, "abc"];
  • 數組可以包含null值, 空數組[]會被當做missing field —— 沒有值的欄位.

2.2 對象類型 - object

JSON文檔是分層的: 文檔可以包含內部對象, 內部對象也可以包含內部對象.

(1) 添加示例:

PUT employee/developer/1
{
    "name": "ma_shoufeng",
    "address": {
        "region": "China",
        "location": {"province": "GuangDong", "city": "GuangZhou"}
    }
}

(2) 存儲方式:

{
    "name":                       "ma_shoufeng",
    "address.region":             "China",
    "address.location.province":  "GuangDong", 
    "address.location.city":      "GuangZhou"
}

(3) 文檔的映射結構類似為:

PUT employee
{
    "mappings": {
        "developer": {
            "properties": {
                "name": { "type": "text", "index": "true" }, 
                "address": {
                    "properties": {
                        "region": { "type": "keyword", "index": "true" },
                        "location": {
                            "properties": {
                                "province": { "type": "keyword", "index": "true" },
                                "city": { "type": "keyword", "index": "true" }
                            }
                        }
                    }
                }
            }
        }
    }
}

2.3 嵌套類型 - nested

嵌套類型是對象數據類型的一個特例, 可以讓array類型的對象被獨立索引和搜索.

2.3.1 對象數組是如何存儲的

① 添加數據:

PUT game_of_thrones/role/1
{
    "group": "stark",
    "performer": [
        {"first": "John", "last": "Snow"},
        {"first": "Sansa", "last": "Stark"}
    ]
}

② 內部存儲結構:

{
    "group":             "stark",
    "performer.first": [ "john", "sansa" ],
    "performer.last":  [ "snow", "stark" ]
}

③ 存儲分析:

可以看出, user.first和user.last會被平鋪為多值欄位, 這樣一來, John和Snow之間的關聯性就丟失了.

在查詢時, 可能出現John Stark的結果.

2.3.2 用nested類型解決object類型的不足

如果需要對以最對象進行索引, 且保留數組中每個對象的獨立性, 就應該使用嵌套數據類型.

—— 嵌套對象實質是將每個對象分離出來, 作為隱藏文檔進行索引.

① 創建映射:

PUT game_of_thrones
{
    "mappings": {
        "role": {
            "properties": {
                "performer": {"type": "nested" }
            }
        }
    }
}

② 添加數據:

PUT game_of_thrones/role/1
{
    "group" : "stark",
    "performer" : [
        {"first": "John", "last": "Snow"},
        {"first": "Sansa", "last": "Stark"}
    ]
}

③ 檢索數據:

GET game_of_thrones/_search
{
    "query": {
        "nested": {
            "path": "performer",
            "query": {
                "bool": {
                    "must": [
                        { "match": { "performer.first": "John" }},
                        { "match": { "performer.last":  "Snow" }} 
                    ]
                }
            }, 
            "inner_hits": {
                "highlight": {
                    "fields": {"performer.first": {}}
                }
            }
        }
    }
}

3 地理數據類型

3.1 地理點類型 - geo point

地理點類型用於存儲地理位置的經緯度對, 可用於:

  • 查找一定範圍內的地理點;
  • 通過地理位置或相對某個中心點的距離聚合文檔;
  • 將距離整合到文檔的相關性評分中;
  • 通過距離對文檔進行排序.

(1) 添加映射:

PUT employee
{
    "mappings": {
        "developer": {
            "properties": {
                "location": {"type": "geo_point"}
            }
        }
    }
}

(2) 存儲地理位置:

// 方式一: 緯度 + 經度鍵值對
PUT employee/developer/1
{
    "text": "小蠻腰-鍵值對地理點參數", 
    "location": {
        "lat": 23.11, "lon": 113.33     // 緯度: latitude, 經度: longitude
    }
}

// 方式二: "緯度, 經度"的字元串參數
PUT employee/developer/2
{
  "text": "小蠻腰-字元串地理點參數",
  "location": "23.11, 113.33"           // 緯度, 經度
}

// 方式三: ["經度, 緯度"] 數組地理點參數
PUT employee/developer/3
{
  "text": "小蠻腰-數組參數",
  "location": [ 113.33, 23.11 ]         // 經度, 緯度
}

(3) 查詢示例:

GET employee/_search
{
    "query": { 
        "geo_bounding_box": { 
            "location": {
                "top_left": { "lat": 24, "lon": 113 },      // 地理盒子模型的上-左邊
                "bottom_right": { "lat": 22, "lon": 114 }   // 地理盒子模型的下-右邊
            }
        }
    }
}

3.2 地理形狀類型 - geo_shape

是多邊形的複雜形狀. 使用較少, 這裡省略.

可以參考這篇文章: Elasticsearch地理位置總結


4 專門數據類型

4.1 IP類型

IP類型的欄位用於存儲IPv4或IPv6的地址, 本質上是一個長整型欄位.

(1) 添加映射:

PUT employee
{
    "mappings": {
        "customer": {
            "properties": {
                "ip_addr": { "type": "ip" }
            }
        }
    }
}

(2) 添加數據:

PUT employee/customer/1
{ "ip_addr": "192.168.1.1" }

(3) 查詢數據:

GET employee/customer/_search
{
    "query": {
        "term": { "ip_addr": "192.168.0.0/16" }
    }
}

4.2 計數數據類型 - token_count

token_count類型用於統計字元串中的單詞數量.

本質上是一個整數型欄位, 接受並分析字元串值, 然後索引字元串中單詞的個數.

(1) 添加映射:

PUT employee
{
    "mappings": {
        "customer": {
            "properties": {
                "name": { 
                    "type": "text",
                    "fields": {
                        "length": {
                            "type": "token_count", 
                            "analyzer": "standard"
                        }
                    }
                }
            }
        }
    }
}

(2) 添加數據:

PUT employee/customer/1
{ "name": "John Snow" }
PUT employee/customer/2
{ "name": "Tyrion Lannister" }

(3) 查詢數據:

GET employee/customer/_search
{
    "query": {
        "term": { "name.length": 2 }
    }
}

參考資料

Elasticsearch 6.6 官方文檔 - Field datatypes

Elasticsearch 5.4 Mapping詳解

版權聲明

作者: 馬瘦風

出處: 博客園 馬瘦風的博客

您的支持是對博主的極大鼓勵, 感謝您的閱讀.

本文版權歸博主所有, 歡迎轉載, 但請保留此段聲明, 併在文章頁面明顯位置給出原文鏈接, 否則博主保留追究相關人員法律責任的權利.


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • Linux 中主要有五種IO模式:阻塞IO, 非阻塞IO, IO 多路復用,信號驅動IO和非同步IO; 如果從同步非同步,阻塞非阻塞角度來看,又可以分為:同步阻塞IO, 同步非阻塞IO,非同步阻塞IO和非同步非阻塞IO; 每種IO模型,都有自己的使用模式,他們對於特定的應用程式都有自己的優點:其簡單分佈如 ...
  • FIO是測試IOPS的非常好的工具,用來對硬體進行壓力測試和驗證。磁碟IO是檢查磁碟性能的重要指標,可以按照負載情況分成照順序讀寫,隨機讀寫兩大類。 目前主流的第三方IO測試工具有fio、iometer 和 Orion,這三種工具各有千秋,在linux 下也可以使用dd 進行簡單的磁碟(文件系統)測 ...
  • 1、下載壓縮包:https://github.com/opencv/opencv,在Branch欄選擇3.4版本,clone下載 2、安裝cmake及依賴庫,打開終端,輸入以下命令: 3、解壓所下載的壓縮包,在包含有CmakeList.txt文件的目錄下右鍵打開終端: 新建文件夾build,並切換到 ...
  • 1.前提 由於之前一直用的機械硬碟,電腦用了幾年是越來越慢,所以打算買個SSD,裝個新系統,其他的機械硬碟都當從盤用 2.準備工作 SSD :256G 3星的 WIN10正版光碟一張 外置光碟機一個 3.踩坑 不知是光碟機問題還是光碟問題,在pc上始終識別失敗,導致始終報錯“reboot and sel ...
  • MYSQL ERROR 2003 (HY000): Can't connect to MySQL server on '192.168.10.210' (111) 解決方法 今天在測試MySQL的連接時候,發現連接不通過,並報錯ERROR 2003 (HY000): Can't connect to ...
  • 1. 數據的抽取 1.1 從資料庫中抽取數據生成本地文件 1.1.1 將“數據流任務”控制項拖入“控制流”視窗 1.1.2 選擇數據源 1.1.2.1 將““OLE DB 源””拖入“數據流”視窗,雙擊編輯屬性 1.1.2.2 新建“連接管理器”,輸入資料庫名稱,選擇連接方式,選擇資料庫名,嘗試連接成 ...
  • 一、主拓展模式 主擴展模式通常用來將幾個相似的對象的共有屬性抽取出來,形成一個”公共屬性表“,且“公共屬性表”與“專有屬性表”是“一對一”的關係。“專有屬性表”可以看做是“公共屬性表”的 擴展,兩者合在一起就是對一個特定對象的完整描述,故此得名“主擴展模式”。 主要適用於,對象的個數不多,各個對象之 ...
  • 1、select(查詢) select簡單的查詢分為兩種 註:欄位也就是表結構中的列的名稱 第一種: select 欄位名 from 表名 此種查詢只列出你所需要查詢的欄位,要查詢多個欄位以“,”隔開 第二種: select * from 表名 * 的意思是查詢出此表的所有欄位 額外的內容:dist ...
一周排行
    -Advertisement-
    Play Games
  • 前言 本文介紹一款使用 C# 與 WPF 開發的音頻播放器,其界面簡潔大方,操作體驗流暢。該播放器支持多種音頻格式(如 MP4、WMA、OGG、FLAC 等),並具備標記、實時歌詞顯示等功能。 另外,還支持換膚及多語言(中英文)切換。核心音頻處理採用 FFmpeg 組件,獲得了廣泛認可,目前 Git ...
  • OAuth2.0授權驗證-gitee授權碼模式 本文主要介紹如何筆者自己是如何使用gitee提供的OAuth2.0協議完成授權驗證並登錄到自己的系統,完整模式如圖 1、創建應用 打開gitee個人中心->第三方應用->創建應用 創建應用後在我的應用界面,查看已創建應用的Client ID和Clien ...
  • 解決了這個問題:《winForm下,fastReport.net 從.net framework 升級到.net5遇到的錯誤“Operation is not supported on this platform.”》 本文內容轉載自:https://www.fcnsoft.com/Home/Sho ...
  • 國內文章 WPF 從裸 Win 32 的 WM_Pointer 消息獲取觸摸點繪製筆跡 https://www.cnblogs.com/lindexi/p/18390983 本文將告訴大家如何在 WPF 裡面,接收裸 Win 32 的 WM_Pointer 消息,從消息裡面獲取觸摸點信息,使用觸摸點 ...
  • 前言 給大家推薦一個專為新零售快消行業打造了一套高效的進銷存管理系統。 系統不僅具備強大的庫存管理功能,還集成了高性能的輕量級 POS 解決方案,確保頁面載入速度極快,提供良好的用戶體驗。 項目介紹 Dorisoy.POS 是一款基於 .NET 7 和 Angular 4 開發的新零售快消進銷存管理 ...
  • ABP CLI常用的代碼分享 一、確保環境配置正確 安裝.NET CLI: ABP CLI是基於.NET Core或.NET 5/6/7等更高版本構建的,因此首先需要在你的開發環境中安裝.NET CLI。這可以通過訪問Microsoft官網下載並安裝相應版本的.NET SDK來實現。 安裝ABP ...
  • 問題 問題是這樣的:第三方的webapi,需要先調用登陸介面獲取Cookie,訪問其它介面時攜帶Cookie信息。 但使用HttpClient類調用登陸介面,返回的Headers中沒有找到Cookie信息。 分析 首先,使用Postman測試該登陸介面,正常返回Cookie信息,說明是HttpCli ...
  • 國內文章 關於.NET在中國為什麼工資低的分析 https://www.cnblogs.com/thinkingmore/p/18406244 .NET在中國開發者的薪資偏低,主要因市場需求、技術棧選擇和企業文化等因素所致。歷史上,.NET曾因微軟的閉源策略發展受限,儘管後來推出了跨平臺的.NET ...
  • 在WPF開發應用中,動畫不僅可以引起用戶的註意與興趣,而且還使軟體更加便於使用。前面幾篇文章講解了畫筆(Brush),形狀(Shape),幾何圖形(Geometry),變換(Transform)等相關內容,今天繼續講解動畫相關內容和知識點,僅供學習分享使用,如有不足之處,還請指正。 ...
  • 什麼是委托? 委托可以說是把一個方法代入另一個方法執行,相當於指向函數的指針;事件就相當於保存委托的數組; 1.實例化委托的方式: 方式1:通過new創建實例: public delegate void ShowDelegate(); 或者 public delegate string ShowDe ...