日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

01.elasticsearch-mapping全面解析

發布時間:2024/2/28 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 01.elasticsearch-mapping全面解析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

    • 1. es index mapping內容概述
    • 2. field data type
      • 1. keyword類型
        • 1. string.text 分詞文本
        • 2. string.keyword 關鍵字文本
        • 3. numeric 數字
        • 4. date 日期
        • 5. date nanoseconds 納秒日期
        • 6. boolean 布爾類型
        • 7. binary 二進制類型
        • 8. range 范圍類型的數據
      • 2. 復合數據類型
        • 1. object 對象類型
        • 2. nested 嵌套類型
      • 3. GEO 地理信息類型
        • 1. geo-point類型,點表示的地理位置信息
        • 2. geo-shape類型,框表示的地理位置信息,一般是標識一個區域范圍
          • 簡單api樣例
      • 4. 專用的數據類型
        • 1. ip 類型數據
        • 2. completion 類型數據,主要是為了支撐查詢提示詞自動補全功能
        • 3. token count 類型,統計string中的token數量
        • 4. mapper-murmurs 類型,計算value的hash值并存儲,對于一些長字段精確檢索有用
        • 5. mapper-annotated-text 類型,在索引該文檔的時候增加一個特殊的mark標識
        • 6. percolator 類型:索引中存儲的是query,然后允許根據document來查詢索引中的哪些query和這個doc有關
        • 7. join 類型: 在一個索引中定義具有父子關系的doc
        • 8. rank future 類型:一個數字類型的存儲,在query的時候允許用來作為boost的一部分時使用
        • 9. rank futures 類型:多個rank future ,在query的時候允許用來作為boost的一部分時使用
        • 10. dense vector : 稠密向量,float類型的向量
        • 11. sparse vector: 稀疏向量,float 類型向量
        • 12. search-as-you-type: 按照你的輸入查詢,類似前綴查詢,更加高效
        • 13. alias 類型:是別的字段的一個別名
        • 14. flattened: 把json類型的復合字段當做一個field進行索引,mapping中不會產生多個字段。
      • 5. Arrays數組類型
      • 6. 多字段類型支持

1. es index mapping內容概述

接下來的這個章節主要介紹es的index的mapping相關的內容。es 的index 像是mysql的一個table,而index的mapping這像是一個table的定義DDL。
比如下面的一個mysql的表定義

| likes_count| CREATE TABLE `likes_count` (`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '自增主鍵',`target_id` bigint(20) NOT NULL DEFAULT '0' COMMENT '喜歡目標id',`target_type` tinyint(8) NOT NULL DEFAULT '0' COMMENT '喜歡目標type',`cnt` bigint(20) NOT NULL DEFAULT '0' COMMENT '喜歡次數',`created_at` bigint(20) NOT NULL DEFAULT '0' COMMENT '創建時間',`updated_at` bigint(20) NOT NULL DEFAULT '0' COMMENT '更新時間',PRIMARY KEY (`id`),UNIQUE KEY `uniq_id_type` (`target_id`,`target_type`) ) ENGINE=InnoDB AUTO_INCREMENT=19 DEFAULT CHARSET=utf8mb4 COMMENT='喜歡次數表'

這個是一個mysql中的table的定義,
1.他定義了該table的name,
2.table有哪些字段field,
3.每個字段的數據類型,
4.每個字段的非空約束,
5.每個字段的默認值和說明內容,
5.還有一些是自增字段的定義AUTO_INCREMENT
6.以及一些索引的定義,PRIMARY KEY,UNIQUE KEY 等
7.table的引擎定義,字符編碼定義等

而es的index mapping的作用也和這個類似,主要是為了約束每個索引中的字段類型,同時因為es和mysql的實現不一樣,所以也會有自己的特別配置,比如分詞器等配置,數據類型支持的可能也并不一樣。當然,es還有index setting相關的設置,那個更多的是類似于對table的設置,index mapping更多的是對每個字段的定義。后面我們也會討論對index 的setting。

es mapping的內容主要有以下幾部分

  • filed data type: 也就是每個field的類型
  • mapping param : 每個filed可以設置的參數(這個類似mysql中的AUTO_INCREMENT類似的關鍵字),這些關鍵字都和es的特性有關系,這部分內容也比較多,如果想要全面理解可能還需要一些lucene的知識
  • meta fields : 也就是在es的index中默認自帶的一些field
  • dynamic mapping: es根據插入的document自動識別字段類型,生成默認的mapping,關于自動生成的機制,用戶有一定的干預空間
  • index template: 這一塊兒是es針對index setting 和index mapping設置的一個便捷功能,可以針對一批未來創建的索引預先設置一個模板。
  • 2. field data type

    es是一個很靈活的存儲系統,可以直接使用json文檔進行插入,即使是多層的json,json字段類型都不同也沒有關系。所以他支持的數據類型就要比較靈活才行。下面來學習一下es的數據類型。

    類型集合綜述

  • keyword類型

  • string.text 分詞文本
  • string.keyword 關鍵字文本
  • numeric 數字
  • date 日期
  • date nanoseconds 納秒日期
  • boolean 布爾類型
  • binary 二進制類型
  • range 范圍類型的數據
  • 復合數據類型

  • object 對象類型
  • nested 嵌套類型
  • GEO 地理信息類型

  • geo-point類型,點表示的地理位置信息
  • geo-shape類型,框表示的地理位置信息,一般是標識一個區域范圍
  • 專用的數據類型

  • ip 類型數據
  • completion 類型數據,主要是為了支撐查詢提示詞自動補全功能
  • token count 類型,統計string中的token數量
  • mapper-murmurs 類型,計算value的hash值并存儲,對于一些長字段精確檢索有用
  • mapper-annotated-text 類型,在索引該文檔的時候增加一個特殊的mark標識
  • percolator 類型:索引中存儲的是query,然后允許根據document來查詢索引中的哪些query和這個doc有關
  • join 類型: 在一個索引中定義具有父子關系的doc
  • rank future 類型:一個數字類型的存儲,在query的時候允許用來作為boost的一部分時使用
  • rank futures 類型:多個rank future ,在query的時候允許用來作為boost的一部分時使用
  • dense vector : 稠密向量,float類型的向量
  • sparse vector: 稀疏向量,float 類型向量
  • search-as-you-type: 按照你的輸入查詢,類似前綴查詢,更加高效
  • alias 類型:是別的字段的一個別名
  • flattened: 把json類型的復合字段當做一個field進行索引,mapping中不會產生多個字段。
  • Arrays數組類型

  • 多字段類型

  • 1. keyword類型

    1. string.text 分詞文本

    PUT my_index {"mappings": {"properties": {"full_name": {"type": "text"}}} }

    這個字段主要用來搜索,很少用來的做聚合操作(當然也可以做聚合操作)
    可以有的設置有

    analyzer
    boost
    eager_global_ordinals
    fielddata
    fields
    index
    index_options
    index_prefixes
    index_phrases
    norms
    position_increment_gap
    store
    search_analyzer
    search_quote_analyzer
    similarity
    term_vector
    這些設置被稱為mapping param,將在后續的博客進行講述

    2. string.keyword 關鍵字文本

    這個就是用來做filter,sort和聚合查詢使用的

    PUT my_index {"mappings": {"properties": {"tags": {"type": "keyword"}}} }

    值得注意的是,對于數值型數據,如果不需要進行范圍查詢,像status僅僅是用來過濾的話,那么可以考慮使用keyword來存儲數值,
    es的term查詢,keyword類型要比數值類型更加高效。
    如果你不太確定的話,可以使用multi-field特性來保存keyword和numeric兩種類型。
    可以有的設置有

    boost
    doc_values
    eager_global_ordinals
    fields
    ignore_above
    index
    index_options
    norms
    null_value
    store
    similarity
    normalizer
    split_queries_on_whitespace
    meta

    3. numeric 數字

    long : 64位整數,負的2的63次方----> 2的63次方-1

    integer: 32位整數,負的2的32次方----> 2的32次方-1

    short: 16位整數,-32,768 -----> 32,767.

    byte: 單字節 -128 -----> 127

    double: 64位浮點數,準尋IEEE 754 標準

    float: 32位浮點數,準尋IEEE 754 標準

    half_float: 16位浮點數,準尋IEEE 754 標準

    scaled_float: 一個浮點數,由一個長整數支持,并由一個固定的雙比例縮放因子縮放

    PUT my_index {"mappings": {"properties": {"number_of_bytes": {"type": "integer"},"time_in_seconds": {"type": "float"},"price": {"type": "scaled_float","scaling_factor": 100}}} }

    需要注意的的對于float,double,half_float類型的數據 -0.0 和 +0.0 是不相等的,查詢的之后需要注意。
    選取的時候根據數值的范圍選擇夠用的即可。

    可以設置的mapping param

    coerce
    boost
    doc_values
    ignore_malformed
    index
    null_value
    store
    meta

    4. date 日期

    因為json沒有json類型,所以es是根據下面的方式來識別date的
    1.特殊類型的string,比如"2015-01-01" or “2015/01/01 12:10:30”.
    2.long類型毫秒級的時間戳
    3.int類型秒級時間戳

    在es內部都是被轉成utc時間,然后存儲為long型的時間戳
    針對date的query都被轉成了range查詢,然后在返回的時候再轉回對應的string pattern,同一個索引中的同一個date field 的數據格式可能是不一樣的,result返回的是你寫入的格式。
    date類型可以設置日期的pattern(通過format屬性進行設置),默認情況下使用 strict_date_optional_time||epoch_millis作為約束
    strict_date_optional_time 這個類型的要求是ISO要求的標準必須是 yyyy-MM-dd'T'HH:mm:ss.SSSZ or yyyy-MM-dd
    我測驗了一下yyyy-MM-dd'T'HH:mm:ss.SSS也是可以的,也就是沒有帶Z,但是這個時候默認加了一個Z,等于是0時區的這個時間。

    樣例

    PUT my_index {"mappings": {"properties": {"date": {"type": "date" }}} }PUT my_index/_doc/1 { "date": "2015-01-01" } PUT my_index/_doc/2 { "date": "2015-01-01T12:10:30Z" } PUT my_index/_doc/3 { "date": 1420070400001 } 然后使用date升序查詢 GET my_index/_search {"sort": { "date": "asc"} }

    返回

    "took" : 209,"timed_out" : false,"_shards" : {"total" : 1,"successful" : 1,"skipped" : 0,"failed" : 0},"hits" : {"total" : {"value" : 3,"relation" : "eq"},"max_score" : null,"hits" : [{"_index" : "my_index","_type" : "_doc","_id" : "1","_score" : null,"_source" : {"date" : "2015-01-01"},"sort" : [1420070400000]},{"_index" : "my_index","_type" : "_doc","_id" : "3","_score" : null,"_source" : {"date" : 1420070400001},"sort" : [1420070400001]},{"_index" : "my_index","_type" : "_doc","_id" : "2","_score" : null,"_source" : {"date" : "2015-01-01T12:10:30Z"},"sort" : [1420114230000]}]} }

    可以看到sort字段都是long類型的timestamp
    同時對于_id=1的doc來說,date字段的值是 1420070400000 ,在本地服務器上轉換為本地時間

    date -d @1420070400 Thu Jan 1 08:00:00 CST 2015

    得到的是 ‘2015-01-01 08:00:00’,這也就說明了如果時間沒有攜帶時間戳,那么就是直接按照utc時間進行計算的,這樣的話,如果這個時間用來在kibana展示的時候可能會有問題,所以如果使用kibana展示的話,時間字段還是要轉成utc這種帶有時區的時間比較準確,否則在es中存儲的就是不準確的時間。

    可以設置的mapping param有

    boost
    doc_values
    format: 設置時間格式
    locale
    ignore_malformed
    index
    null_value
    store
    meta

    你也可以自己設置format屬性,比如

    PUT my_index {"mappings": {"properties": {"date": {"type": "date","format": "yyyy-MM-dd"}}} }

    5. date nanoseconds 納秒日期

    這個存儲的是一個long的類型,標識納秒的時間戳,因為long的限制,只能表示1970-2262
    在返回時再轉換成原來的格式。

    date類型可以設置index時候日期的pattern,默認情況下使用 strict_date_optional_time||epoch_millis作為約束
    strict_date_optional_time 這個類型的要求是ISO要求的標準必須是 yyyy-MM-dd'T'HH:mm:ss.SSSZ or yyyy-MM-dd
    我測驗了一下yyyy-MM-dd'T'HH:mm:ss.SSS也是可以的,也就是沒有帶Z,但是這個時候默認加了一個Z,等于是0時區的這個時間。
    但是這個時候其實是會丟失精度的,因為精度只能到毫秒級別。
    建議使用 strict_date_optional_time_nanos
    這個類型的格式是 yyyy-MM-dd'T'HH:mm:ss.SSSSSSZ or yyyy-MM-dd

    PUT my_index?include_type_name=true {"mappings": {"_doc": {"properties": {"date": {"type": "date_nanos" }}}}

    6. boolean 布爾類型

    這個字段相對來說比較簡單,就是 true|false, 就是在index的時候可以寫入string類型的true,false
    返回的時候也還是原來的文檔的模樣,也就是index的是帶字符的返回的也是帶字符的

    PUT my_index {"mappings": {"properties": {"is_published": {"type": "boolean"}}} }POST my_index/_doc/1 {"is_published": "true" }POST my_index/_doc/2 {"is_published": true }GET my_index/_search {"query": {"term": {"is_published": true }} }返回關鍵部分 "hits" : [{"_index" : "my_index","_type" : "_doc","_id" : "1","_score" : 0.18232156,"_source" : {"is_published" : "true"}},{"_index" : "my_index","_type" : "_doc","_id" : "2","_score" : 0.18232156,"_source" : {"is_published" : true}}]

    在 term agg 查詢的時候返回的是0,1

    POST my_index/_doc/1 {"is_published": true }POST my_index/_doc/2 {"is_published": false }GET my_index/_search {"aggs": {"publish_state": {"terms": {"field": "is_published"}}},"script_fields": {"is_published": {"script": {"lang": "painless","source": "doc['is_published']"}}} }

    返回

    {"took" : 4,"timed_out" : false,"_shards" : {"total" : 1,"successful" : 1,"skipped" : 0,"failed" : 0},"hits" : {"total" : {"value" : 2,"relation" : "eq"},"max_score" : 1.0,"hits" : [{"_index" : "my_index","_type" : "_doc","_id" : "1","_score" : 1.0,"fields" : {"is_published" : [true]}},{"_index" : "my_index","_type" : "_doc","_id" : "2","_score" : 1.0,"fields" : {"is_published" : [false]}}]},"aggregations" : {"publish_state" : {"doc_count_error_upper_bound" : 0,"sum_other_doc_count" : 0,"buckets" : [{"key" : 0,"key_as_string" : "false","doc_count" : 1},{"key" : 1,"key_as_string" : "true","doc_count" : 1}]}} }

    在script_field 中返回的是true,false

    7. binary 二進制類型

    二進制類型寫入的時候必須是base64類型的字符串,這個字段默認不會單獨存儲,而且不能被搜索。

    PUT my_index {"mappings": {"properties": {"name": {"type": "text"},"blob": {"type": "binary"}}} }PUT my_index/_doc/1 {"name": "Some binary blob","blob": "U29tZSBiaW5hcnkgYmxvYg==" }

    可以有的mapping param

    doc_values
    store

    8. range 范圍類型的數據

    range 類型很有意思,比如淘寶經常做活動,活動都有開始時間和結束時間,正常情況下需要在mysql中使用兩個字段存儲,但是在es中只使用一個field就可存儲并且可以用來查詢。
    類型有
    integer_range: 范圍同integer
    float_range: 范圍同float
    long_range: 范圍同long
    double_range: 范圍同double
    date_range: 64為毫秒
    ip_range: ipv4 ipv6都支持

    numberic range 樣例

    PUT range_index {"settings": {"number_of_shards": 2},"mappings": {"properties": {"expected_attendees": {"type": "integer_range"},"time_frame": {"type": "date_range", "format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"}}} }PUT range_index/_doc/1?refresh {"expected_attendees" : { "gte" : 10,"lte" : 20},"time_frame" : { "gte" : "2015-10-31 12:00:00", "lte" : "2015-11-01"} }GET range_index/_search {"query" : {"term" : {"expected_attendees" : {"value": 12}}} }GET range_index/_search {"query" : {"range": {"expected_attendees": {"gte": 11,"lte": 20 }}} }GET range_index/_search {"query" : {"range": {"expected_attendees": {"gte": 10,"lte": 21,"relation" : "within"}}} }

    relation 標識目標文檔和當前條件的關系,within,標識目標文檔的字段范圍是條件的子集(可以完全重合)。

    time range 樣例

    GET range_index/_search {"query" : {"range" : {"time_frame" : { "gte" : "2015-10-31","lte" : "2015-11-01","relation" : "within" }}} }

    ip range 樣例

    PUT range_index/_mapping {"properties": {"ip_allowlist": {"type": "ip_range"}} }PUT range_index/_doc/2 {"ip_allowlist" : "192.168.0.0/16" }GET range_index/_search {"query": {"term": {"ip_allowlist": {"value": "192.168.0.1"}}} }

    ip地址使用CIDR表示方法:IP地址/網絡ID的位數
    比如
    192.168.23.35/21
    子網的網絡ID: 192.168.16.0
    子網掩碼:255.255.248.0
    起止IP地址: 192.168.16.1-192.168.23.254

    參考這里

    2. 復合數據類型

    1. object 對象類型

    object 是一個嵌套結構,就是內部又有一些子屬性

    PUT my_index/_doc/1 { "region": "US","manager": { "age": 30,"name": { "first": "John","last": "Smith"}} }

    在實際的存儲當中,這個對象是展開了存儲的就像下面這樣

    {"region": "US","manager.age": 30,"manager.name.first": "John","manager.name.last": "Smith" }

    對應的index mapping 是

    PUT my_index {"mappings": {"properties": { "region": {"type": "keyword"},"manager": { "properties": {"age": { "type": "integer" },"name": { "properties": {"first": { "type": "text" },"last": { "type": "text" }}}}}}} }

    你不用顯式的去指定manage 或者 manage.name的type,默認就是object。
    但是如果你存儲的是array類型的object的話,建議使用nested type

    可以設置的mapping param

    dynamic:
    enabled:json是否應該被識別轉換并放進該field
    properties: object 內部對應的fields

    2. nested 嵌套類型

    類似于object類型,區別是,如果存儲的是數組對象的話,數組中的每個對象能夠以獨立的方式被檢索出來。

    PUT my_index/_doc/1 {"group" : "fans","user" : [ {"first" : "John","last" : "Smith"},{"first" : "Alice","last" : "White"}] }

    上面的寫入產生的的默認mapping中user就是object類型的,他的存儲會變成這樣

    {"group" : "fans","user.first" : [ "alice", "john" ],"user.last" : [ "smith", "white" ] }

    當我們用

    GET my_index/_search {"query": {"bool": {"must": [{ "match": { "user.first": "Alice" }},{ "match": { "user.last": "Smith" }}]}} }

    這樣的query會把這個doc查出來,這顯然是不對的。
    但是當我們使用nested 類型定義的時候就不會出現這個問題了。
    同時,也要使用nested query進行查詢。

    PUT my_index {"mappings": {"properties": {"user": {"type": "nested"}}},"settings": {"index.mapping.nested_fields.limit":20,"index.mapping.nested_objects.limit":100}}PUT my_index/_doc/1 {"group" : "fans","user" : [{"first" : "John","last" : "Smith"},{"first" : "Alice","last" : "White"}] }GET my_index/_search {"query": {"nested": {"path": "user","query": {"bool": {"must": [{ "match": { "user.first": "Alice" }},{ "match": { "user.last": "Smith" }} ]}}}} }

    由于嵌套文檔被索引為單獨的文檔,因此只能在nested查詢,nested/ reverse_nested agg 或nested inner hits 內訪問它們。
    由于嵌套文檔被索引為單獨的文檔,所以包含多個nested object的數組會占用很多個doc,算是一個比較昂貴的mappings.因此es還增加了一些設置進行限制。
    index.mapping.nested_fields.limit: nested field 的數量,默認50
    index.mapping.nested_objects.limit: 每個doc中所有nested字段中可以存儲的nested對象的數量。

    可以設置的mapping param
    dynamic
    properties
    include_in_parent
    include_in_root

    3. GEO 地理信息類型

    1. geo-point類型,點表示的地理位置信息

    存儲的是geo的點數據,可以使用geo-box,或者distance 距離進行查詢
    可以按照距離或者geographically進行agg
    把score和距離相關
    使用distance對doc進行sort 排序

    geo-box查詢樣例

    PUT my_index {"mappings": {"properties": {"location": {"type": "geo_point"}}} }PUT my_index/_doc/1 {"text": "Geo-point as an object","location": { "lat": 41.12,"lon": -71.34} }PUT my_index/_doc/2 {"text": "Geo-point as a string","location": "41.12,-71.34" }PUT my_index/_doc/3 {"text": "Geo-point as a geohash","location": "drm3btev3e86" }PUT my_index/_doc/4 {"text": "Geo-point as an array","location": [ -71.34, 41.12 ] }PUT my_index/_doc/5 {"text": "Geo-point as a WKT POINT primitive","location" : "POINT (-71.34 41.12)" }GET my_index/_search {"query": {"geo_bounding_box": { "location": {"top_left": {"lat": 42,"lon": -72},"bottom_right": {"lat": 40,"lon": -74}}}} }

    可以有的mapping param

    ignore_malformed
    ignore_z_value: true的話,會接收3維的point數據,但是只有二維的進行索引。
    null_value

    2. geo-shape類型,框表示的地理位置信息,一般是標識一個區域范圍

    geo-shape顧名思義,就像是range-number一樣,表達的是一個區域的地理位置
    實際上他支持點,線,面 的存儲,具體的原理好像比較復雜,等后面看具體的查詢的時候再回過來看。
    這里只簡單看一下支持的數據類型

    支持的shape的類型

  • Point : 點
  • LineString : 線,不一定是直線
  • Polygon : 多邊形
  • MultiPoint : 多個點
  • MultiLineString: 多條線
  • MultiPolygon: 多個多邊形
  • GeometryCollection: 幾何圖形集合
  • 簡單api樣例
  • Point : 點
  • POST /example/_doc {"location" : {"type" : "point","coordinates" : [-77.03653, 38.897676]} } POST /example/_doc {"location" : "POINT (-77.03653 38.897676)" }
  • LineString : 線,不一定是直線
  • POST /example/_doc {"location" : {"type" : "linestring","coordinates" : [[-77.03653, 38.897676], [-77.009051, 38.889939]]} }POST /example/_doc {"location" : "LINESTRING (-77.03653 38.897676, -77.009051 38.889939)" }
  • Polygon : 多邊形
  • POST /example/_doc {"location" : {"type" : "polygon","coordinates" : [[ [100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0] ]]} }POST /example/_doc {"location" : "POLYGON ((100.0 0.0, 101.0 0.0, 101.0 1.0, 100.0 1.0, 100.0 0.0))" }環狀區域標識 POST /example/_doc {"location" : {"type" : "polygon","coordinates" : [[ [100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0] ],[ [100.2, 0.2], [100.8, 0.2], [100.8, 0.8], [100.2, 0.8], [100.2, 0.2] ]]} }POST /example/_doc {"location" : "POLYGON ((100.0 0.0, 101.0 0.0, 101.0 1.0, 100.0 1.0, 100.0 0.0), (100.2 0.2, 100.8 0.2, 100.8 0.8, 100.2 0.8, 100.2 0.2))" }
  • MultiPoint : 多個點
  • POST /example/_doc {"location" : {"type" : "multipoint","coordinates" : [[102.0, 2.0], [103.0, 2.0]]} }POST /example/_doc {"location" : "MULTIPOINT (102.0 2.0, 103.0 2.0)" }
  • MultiLineString: 多條線
  • POST /example/_doc {"location" : {"type" : "multilinestring","coordinates" : [[ [102.0, 2.0], [103.0, 2.0], [103.0, 3.0], [102.0, 3.0] ],[ [100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0] ],[ [100.2, 0.2], [100.8, 0.2], [100.8, 0.8], [100.2, 0.8] ]]} }POST /example/_doc {"location" : "MULTILINESTRING ((102.0 2.0, 103.0 2.0, 103.0 3.0, 102.0 3.0), (100.0 0.0, 101.0 0.0, 101.0 1.0, 100.0 1.0), (100.2 0.2, 100.8 0.2, 100.8 0.8, 100.2 0.8))" }
  • MultiPolygon: 多個多邊形
  • POST /example/_doc {"location" : {"type" : "multipolygon","coordinates" : [[ [[102.0, 2.0], [103.0, 2.0], [103.0, 3.0], [102.0, 3.0], [102.0, 2.0]] ],[ [[100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0]],[[100.2, 0.2], [100.8, 0.2], [100.8, 0.8], [100.2, 0.8], [100.2, 0.2]] ]]} }POST /example/_doc {"location" : "MULTIPOLYGON (((102.0 2.0, 103.0 2.0, 103.0 3.0, 102.0 3.0, 102.0 2.0)), ((100.0 0.0, 101.0 0.0, 101.0 1.0, 100.0 1.0, 100.0 0.0), (100.2 0.2, 100.8 0.2, 100.8 0.8, 100.2 0.8, 100.2 0.2)))" }
  • GeometryCollection: 幾何圖形集合
  • POST /example/_doc {"location" : {"type": "geometrycollection","geometries": [{"type": "point","coordinates": [100.0, 0.0]},{"type": "linestring","coordinates": [ [101.0, 0.0], [102.0, 1.0] ]}]} }

    mapping param

    orientation: 對于多邊形的多個點,按照什么方向連點成線再成多邊形
    ignore_malformed
    ignore_z_value
    coerce

    4. 專用的數據類型

    1. ip 類型數據

    可以存儲ipv4 ipv6數據

    PUT my_index {"mappings": {"properties": {"ip_addr": {"type": "ip"}}} }PUT my_index/_doc/1 {"ip_addr": "192.168.1.1" }GET my_index/_search {"query": {"term": {"ip_addr": "192.168.0.0/16"}} }

    這里因為網絡地址是前面16位,主機地址是后面16位,所以可以查出來對應的文檔

    對應的mapping param
    boost
    doc_values
    index
    null_value
    store

    2. completion 類型數據,主要是為了支撐查詢提示詞自動補全功能

    這種類型是為了completion suggester 而創建的,就是為了查詢補全提供的功能,不具備糾錯的能力
    同時es也做了很多優化使查詢很快,但是代價就是index的時候比較慢,而且都存儲于內存當中,對于數據量較小的情況下比較適合。

    PUT music {"mappings": {"properties" : {"suggest" : {"type" : "completion"},"title" : {"type": "keyword"}}} }

    寫入文檔

    PUT music/_doc/1?refresh {"suggest" : {"input": [ "Nevermind", "Nirvana" ],"weight" : 34} }PUT music/_doc/1?refresh {"suggest" : [{"input": "Nevermind","weight" : 10},{"input": "Nirvana","weight" : 3}] }PUT music/_doc/1?refresh {"suggest" : [ "Nevermind", "Nirvana" ] }PUT music/_doc/2?refresh {"suggest" : [ "my house is beautiful" ] }

    查詢文檔

    POST music/_search?pretty {"suggest": {"song-suggest" : {"prefix" : "nir", "completion" : { "field" : "suggest" }}} } POST music/_search?pretty {"suggest": {"song-suggest" : {"prefix" : "nor","completion" : {"field" : "suggest","size" : 5 ,"skip_duplicates": true}}

    上面的查詢結果都是

    ... {"took" : 1,"timed_out" : false,"_shards" : {"total" : 1,"successful" : 1,"skipped" : 0,"failed" : 0},"hits" : {"total" : {"value" : 0,"relation" : "eq"},"max_score" : null,"hits" : [ ]},"suggest" : {"song-suggest" : [{"text" : "nir","offset" : 0,"length" : 3,"options" : [{"text" : "Nirvana","_index" : "music","_type" : "_doc","_id" : "1","_score" : 34.0,"_source" : {"suggest" : {"input" : ["Nevermind","Nirvana"],"weight" : 34}}}]}]} }

    下面這個查詢沒有結果,因為他只能從文檔的頭部開始命中,把house替換為my,則查詢結果就出來了

    POST music/_search?pretty {"suggest": {"song-suggest" : {"prefix" : "house","completion" : {"field" : "suggest"}}} }

    可以使用的mapping param

    analyzer : index使用的analyzer默認為simple
    search_analyzer: 默認同analyzer
    preserve_separators: 是否保留分割符,默認是true,如果是false, Foo Fighters的內容會被 foof的suggest的查詢命中
    preserve_position_increments:
    max_input_length

    3. token count 類型,統計string中的token數量

    token_count 類型的field實際上是一個integer類型,他接收一個text字段,然后將其分詞,存儲其token的數量,一般情況下會使用fileds功能作為一個text字段的輔助字段來使用

    PUT my_index {"mappings": {"properties": {"name": { "type": "text","fields": {"length": { "type": "token_count","analyzer": "standard"}}}}} }PUT my_index/_doc/1 { "name": "John Smith" }PUT my_index/_doc/2 { "name": "Rachel Alice Williams" }GET my_index/_search {"query": {"term": {"name.length": 3 }} }

    mapping param

    analyzer
    enable_position_increments
    boost
    doc_values
    index
    null_value
    store

    4. mapper-murmurs 類型,計算value的hash值并存儲,對于一些長字段精確檢索有用

    這個需要先裝插件才行

    sudo bin/elasticsearch-plugin install mapper-murmur3 PUT my_index {"mappings": {"properties": {"my_field": {"type": "keyword","fields": {"hash": {"type": "murmur3"}}}}} } # Example documents PUT my_index/_doc/1 {"my_field": "This is a document" }PUT my_index/_doc/2 {"my_field": "This is another document" }GET my_index/_search {"aggs": {"my_field_cardinality": {"cardinality": {"field": "my_field.hash" }}} }

    使用hash進行聚合操作的話效率會高出很多。

    5. mapper-annotated-text 類型,在索引該文檔的時候增加一個特殊的mark標識

    類似于命名實體識別能力,給一個field 進行標記,增加一些特定的詞匯
    這個也要插件支持

    sudo bin/elasticsearch-plugin install mapper-annotated-text

    使用樣例

    PUT my_index {"mappings": {"properties": {"my_field": {"type": "annotated_text"}}} }PUT my_index/_doc/1 {"my_field": "[Beck](Beck) announced a new tour" }PUT my_index/_doc/2 {"my_field": "[Jeff Beck](Jeff+Beck&Guitarist) plays a strat" }# Example search GET my_index/_search {"query": {"term": {"my_field": "Beck" }} }

    這種情況下只有第一個文檔會被檢索出來,第二個不會
    因為 Jeff Beck 這個是一個固定的格式,中括號中的會被識別為一個token,小括號內會識別成同義詞。

    比如下面的實驗

    GET my_index/_analyze {"field": "my_field","text":"Investors in [Apple](Apple+Inc.) rejoiced." }

    返回

    {"tokens": [{"token": "investors","start_offset": 0,"end_offset": 9,"type": "<ALPHANUM>","position": 0},{"token": "in","start_offset": 10,"end_offset": 12,"type": "<ALPHANUM>","position": 1},{"token": "Apple Inc.", "start_offset": 13,"end_offset": 18,"type": "annotation","position": 2},{"token": "apple","start_offset": 13,"end_offset": 18,"type": "<ALPHANUM>","position": 2},{"token": "rejoiced","start_offset": 19,"end_offset": 27,"type": "<ALPHANUM>","position": 3}] }

    可以看到apple 和Apple Inc. 的索引位置position是一樣的,被識別為同義詞一樣的東西。

    6. percolator 類型:索引中存儲的是query,然后允許根據document來查詢索引中的哪些query和這個doc有關

    這個可能是在需要對文檔進行反向查詢的時候使用更加合適,參考這里
    舉例:提供一個存儲用戶興趣的平臺,以便在每次有新內容進入時將正確的內容(通知警報)發送給正確的用戶。
    舉例:用戶訂閱了特定主題,以便一旦該主題的新文章出現,就會向感興趣的用戶發送通知。
    有些對doc進行分類的意思

    應用場景如下:
    價格監控
    新聞警報

    他的使用方式是

  • 使用索引存儲查詢語句很多條查詢語句
  • 使用一個doc對該索引進行query,看看命中的是哪個query
  • 但是實際上使用起來看著有點不是很習慣,可能還是看的少

    PUT index {"mappings": {"properties": {"query" : {"type" : "percolator"},"body" : {"type": "text"}}} }PUT index/_doc/1?refresh {"query" : {"match" : {"body" : "quick brown fox"}} }PUT index/_doc/2?refresh {"query" : {"match" : {"body" : "fox jumps over"}} }GET /index/_search {"query": {"percolate" : {"field" : "query","document" : {"body" : "fox jumps over the lazy dog"}}} }

    返回

    {"took" : 6,"timed_out" : false,"_shards" : {"total" : 1,"successful" : 1,"skipped" : 0,"failed" : 0},"hits" : {"total" : {"value" : 2,"relation" : "eq"},"max_score" : 0.39229372,"hits" : [{"_index" : "index","_type" : "_doc","_id" : "2","_score" : 0.39229372,"_source" : {"query" : {"match" : {"body" : "fox jumps over"}}},"fields" : {"_percolator_document_slot" : [0]}},{"_index" : "index","_type" : "_doc","_id" : "1","_score" : 0.13076457,"_source" : {"query" : {"match" : {"body" : "quick brown fox"}}},"fields" : {"_percolator_document_slot" : [0]}}]} }

    這個返回的結構似乎和其他的略有不同

    樣例二

    PUT percolator {"mappings": {"properties": {"dsl":{"type": "percolator"},"message":{"type": "text"}}} }POST percolator/_doc/2 {"dsl": {"match": {"message": "to be better or bad " # 這里dsl字段中使用的query對應的message字段必須在percolator 的mapping當中已經定義了才能正常的使用}} }GET percolator/_search {"query": {"percolate": {"field": "dsl","document": {"message":"bad information"}}} }返回 "hits" : {"total" : {"value" : 1,"relation" : "eq"},"max_score" : 0.13076457,"hits" : [{"_index" : "percolator","_type" : "_doc","_id" : "2","_score" : 0.13076457,"_source" : {"dsl" : {"match" : {"message" : "to be better or bad "}}},"fields" : {"_percolator_document_slot" : [0]}}]}

    percolator 的查詢原理是存儲 query到index01中,然后使用document查詢的時候,使用該doc對query進行一次召回,然后再將該doc創建內存索引index02,使用召回的query在index02中進行查詢,然后進行相關度打分并返回

    7. join 類型: 在一個索引中定義具有父子關系的doc

    join 類型主要是輔助你在一個索引中定義具有父子關系的doc

    使用樣例

    PUT my_index {"mappings": {"properties": {"my_join_field": { "type": "join","relations": {"question": "answer" }}}} }PUT my_index/_doc/1?refresh {"text": "This is a question","my_join_field": {"name": "question" } }PUT my_index/_doc/2?refresh {"text": "This is another question","my_join_field": {"name": "question"} }PUT my_index/_doc/3?routing=1&refresh {"text": "This is an answer","my_join_field": {"name": "answer", "parent": "1" } }PUT my_index/_doc/4?routing=1&refresh {"text": "This is another answer","my_join_field": {"name": "answer","parent": "1"} }GET my_index/_search

    查詢返回

    ... "hits" : {"total" : {"value" : 4,"relation" : "eq"},"max_score" : 1.0,"hits" : [{"_index" : "my_index","_type" : "_doc","_id" : "1","_score" : 1.0,"_source" : {"text" : "This is a question","my_join_field" : {"name" : "question"}}},{"_index" : "my_index","_type" : "_doc","_id" : "2","_score" : 1.0,"_source" : {"text" : "This is another question","my_join_field" : {"name" : "question"}}},{"_index" : "my_index","_type" : "_doc","_id" : "3","_score" : 1.0,"_routing" : "1","_source" : {"text" : "This is an answer","my_join_field" : {"name" : "answer","parent" : "1"}}},{"_index" : "my_index","_type" : "_doc","_id" : "4","_score" : 1.0,"_routing" : "1","_source" : {"text" : "This is another answer","my_join_field" : {"name" : "answer","parent" : "1"}}}]}

    然后使用更加復雜的查詢試試

    GET my_index/_search {"query": {"parent_id": { "type": "answer","id": "1"}},"aggs": {"parents": {"terms": {"field": "my_join_field#question", "size": 10}}},"script_fields": {"parent": {"script": {"source": "doc['my_join_field#question']" }}} }

    查詢返回

    "hits" : {"total" : {"value" : 2,"relation" : "eq"},"max_score" : 0.35667494,"hits" : [{"_index" : "my_index","_type" : "_doc","_id" : "3","_score" : 0.35667494,"_routing" : "1","fields" : {"parent" : ["1"]}},{"_index" : "my_index","_type" : "_doc","_id" : "4","_score" : 0.35667494,"_routing" : "1","fields" : {"parent" : ["1"]}}]},"aggregations" : {"parents" : {"doc_count_error_upper_bound" : 0,"sum_other_doc_count" : 0,"buckets" : [{"key" : "1","doc_count" : 2}]}}

    為了加速join查詢,會使用全局基數來進行加速,這就需要當前shard的doc發生變化之后重建全局基數。parent id越多,重建的代價也約高。
    對于有join field的index來說,全局基數默認會進行重建,重建的任務稱為refresh任務的一部分。
    如果禁用了立即重建,會在第一次使用join查詢或者agg查詢的時候進行重建,有可能導致查詢超時。

    同時使用上還有一些限制

  • 一個index中只能有一個join field
  • parent doc 和child doc只能在一個shard上,這樣查詢才會有效,所以parent 和child 進行index操作的時候指定的 routing必須是同一個。
  • parent可以有多個child,但是一個child只能有一個parent
  • 在已經存在的join field上可以增加新的關系
  • parent下可以增加新的child
  • 感覺這個在大規模的數據當中使用可能還是會有一些性能問題,尤其是那種頻繁更新的數據。

    8. rank future 類型:一個數字類型的存儲,在query的時候允許用來作為boost的一部分時使用

    聽說這個是es支持機器學習的一個部分
    查詢的時候也必須用rank_feture 查詢哦,就是一種特殊的查詢,類似term,match_all 等,具體看下面的例子

    DELETE my_index PUT my_index {"mappings": {"properties": {"pagerank": {"type": "rank_feature" },"url_length": {"type": "rank_feature","positive_score_impact": false }}} }PUT my_index/_doc/1 {"pagerank": 8,"url_length": 22 }PUT my_index/_doc/2 {"pagerank": 9,"url_length": 22 }GET my_index/_search {"query": {"rank_feature": {"field": "pagerank"}},"explain": true }

    查詢返回

    {"took" : 1,"timed_out" : false,"_shards" : {"total" : 1,"successful" : 1,"skipped" : 0,"failed" : 0},"hits" : {"total" : {"value" : 2,"relation" : "eq"},"max_score" : 0.5142857,"hits" : [{"_shard" : "[my_index][0]","_node" : "ADi2c-NmTnWhTmb2dDlCeA","_index" : "my_index","_type" : "_doc","_id" : "2","_score" : 0.5142857,"_source" : {"pagerank" : 9,"url_length" : 22},"_explanation" : {"value" : 0.5142857,"description" : "Saturation function on the _feature field for the pagerank feature, computed as w * S / (S + k) from:","details" : [{"value" : 1.0,"description" : "w, weight of this function","details" : [ ]},{"value" : 8.5,"description" : "k, pivot feature value that would give a score contribution equal to w/2","details" : [ ]},{"value" : 9.0,"description" : "S, feature value","details" : [ ]}]}},{"_shard" : "[my_index][0]","_node" : "ADi2c-NmTnWhTmb2dDlCeA","_index" : "my_index","_type" : "_doc","_id" : "1","_score" : 0.4848485,"_source" : {"pagerank" : 8,"url_length" : 22},"_explanation" : {"value" : 0.4848485,"description" : "Saturation function on the _feature field for the pagerank feature, computed as w * S / (S + k) from:","details" : [{"value" : 1.0,"description" : "w, weight of this function","details" : [ ]},{"value" : 8.5,"description" : "k, pivot feature value that would give a score contribution equal to w/2","details" : [ ]},{"value" : 8.0,"description" : "S, feature value","details" : [ ]}]}}]} }

    這個公式我暫時先不聊,應該在rank_feature query中會再出現的。

    9. rank futures 類型:多個rank future ,在query的時候允許用來作為boost的一部分時使用

    這個和上一個類似,只是可以存儲特征向量

    使用樣例

    PUT my_index {"mappings": {"properties": {"topics": {"type": "rank_features" }}} }PUT my_index/_doc/1 {"topics": { "politics": 20,"economics": 50.8} }PUT my_index/_doc/2 {"topics": {"politics": 5.2,"sports": 80.1} }GET my_index/_search {"query": {"rank_feature": {"field": "topics.politics"}} }

    10. dense vector : 稠密向量,float類型的向量

    稠密向量,這個簡直是顧名思義,哈哈
    一般是用來計算文檔的score的時候使用
    理論上一個向量的維度不應該超過1024

    PUT my_index {"mappings": {"properties": {"my_vector": {"type": "dense_vector","dims": 3 },"my_text" : {"type" : "keyword"}}} }PUT my_index/_doc/1 {"my_text" : "text1","my_vector" : [0.5, 10, 6] }PUT my_index/_doc/2 {"my_text" : "text2","my_vector" : [-0.5, 10, 10] }GET my_index/_search {"query": {"script_score": {"query": {"match_all": {}},"script": {"source": "cosineSimilarity(params.queryVector, doc['my_vector'])","params": {"queryVector": [4, 3.4, -0.2] }}}} }

    返回

    "hits" : {"total" : {"value" : 2,"relation" : "eq"},"max_score" : 0.5674877,"hits" : [{"_index" : "my_index","_type" : "_doc","_id" : "1","_score" : 0.5674877,"_source" : {"my_text" : "text1","my_vector" : [0.5,10,6]}},{"_index" : "my_index","_type" : "_doc","_id" : "2","_score" : 0.4035343,"_source" : {"my_text" : "text2","my_vector" : [-0.5,10,10]}}]}

    11. sparse vector: 稀疏向量,float 類型向量

    稀疏向量,為了應對多維度但是又比較稀疏的向量

    DELETE my_index PUT my_index {"mappings": {"properties": {"my_vector": {"type": "sparse_vector"},"my_text" : {"type" : "keyword"}}} }PUT my_index/_doc/1 {"my_text" : "text1","my_vector" : {"1": 0.5, "5": -0.5, "100": 1} }PUT my_index/_doc/2 {"my_text" : "text2","my_vector" : {"103": 0.5, "4": -0.5, "5": 1, "11" : 1.2} }GET my_index/_search {"query": {"script_score": {"query": {"match_all": {}},"script": {"source": "cosineSimilaritySparse(params.queryVector, doc['my_vector'])","params": {"queryVector": {"2": 0.5, "10" : 111.3, "50": -1.3, "113": 14.8, "4545": 156.0}}}}} }

    返回

    ..."hits" : {"total" : {"value" : 2,"relation" : "eq"},"max_score" : 0.0,"hits" : [{"_index" : "my_index","_type" : "_doc","_id" : "1","_score" : 0.0,"_source" : {"my_text" : "text1","my_vector" : {"1" : 0.5,"5" : -0.5,"100" : 1}}},{"_index" : "my_index","_type" : "_doc","_id" : "2","_score" : 0.0,"_source" : {"my_text" : "text2","my_vector" : {"103" : 0.5,"4" : -0.5,"5" : 1,"11" : 1.2}}}]}

    12. search-as-you-type: 按照你的輸入查詢,類似前綴查詢,更加高效

    感覺這個有點類似prefix query,底層做了不少優化,使查詢的效率更高
    但是代價是增加了不少存儲??聪旅娴囊粋€例子

    PUT my_index {"mappings": {"properties": {"my_field": {"type": "search_as_you_type","analyzer": "standard"}}} }

    上面的mapping會產生下面幾個字段

    my_field: 使用對應的analyzer 產生該字段的token
    my_field._2gram: 使用shingle token filter 對my_field產出的token按照2gram處理形成當前字段的token
    my_field._3gram: 使用shingle token filter 對my_field產出的token按照3gram處理形成當前字段的token
    my_field._index_prefix: 使用 edge ngram token filter 對my_field._3gram產出的token進行處理形成當前字段的token

    使用analyze api測試

    POST my_index/_analyze {"field": "my_field","text": ["quick brown fox "]}返回{"tokens" : [{"token" : "quick","start_offset" : 0,"end_offset" : 5,"type" : "<ALPHANUM>","position" : 0},{"token" : "brown","start_offset" : 6,"end_offset" : 11,"type" : "<ALPHANUM>","position" : 1},{"token" : "fox","start_offset" : 12,"end_offset" : 15,"type" : "<ALPHANUM>","position" : 2}] }

    測試2gram

    POST my_index/_analyze {"field": "my_field._2gram","text": ["quick brown fox"]}返回 {"tokens" : [{"token" : "quick brown","start_offset" : 0,"end_offset" : 11,"type" : "shingle","position" : 0},{"token" : "brown fox","start_offset" : 6,"end_offset" : 15,"type" : "shingle","position" : 1}] }

    測試3gram

    POST my_index/_analyze {"field": "my_field._3gram","text": ["quick brown fox"]}返回 {"tokens" : [{"token" : "quick brown fox","start_offset" : 0,"end_offset" : 15,"type" : "shingle","position" : 0}] }

    測試_index_prefix

    POST my_index/_analyze {"field": "my_field._index_prefix","text": ["quick brown fox"]}返回{"tokens" : [{"token" : "q", "start_offset" : 0, "end_offset" : 15, "type" : "shingle", "position" : 0 },{"token" : "qu", "start_offset" : 0, "end_offset" : 15, "type" : "shingle", "position" : 0 },{"token" : "qui", "start_offset" : 0, "end_offset" : 15, "type" : "shingle", "position" : 0 },{"token" : "quic", "start_offset" : 0, "end_offset" : 15, "type" : "shingle", "position" : 0 },{"token" : "quick", "start_offset" : 0, "end_offset" : 15, "type" : "shingle", "position" : 0 },{"token" : "quick ", "start_offset" : 0, "end_offset" : 15, "type" : "shingle", "position" : 0 },{"token" : "quick b", "start_offset" : 0, "end_offset" : 15, "type" : "shingle", "position" : 0 },{"token" : "quick br", "start_offset" : 0, "end_offset" : 15, "type" : "shingle", "position" : 0 },{"token" : "quick bro", "start_offset" : 0, "end_offset" : 15, "type" : "shingle", "position" : 0 },{"token" : "quick brow", "start_offset" : 0, "end_offset" : 15, "type" : "shingle", "position" : 0 },{"token" : "quick brown", "start_offset" : 0, "end_offset" : 15, "type" : "shingle", "position" : 0 },{"token" : "quick brown ", "start_offset" : 0, "end_offset" : 15, "type" : "shingle", "position" : 0 },{"token" : "quick brown f", "start_offset" : 0, "end_offset" : 15, "type" : "shingle", "position" : 0 },{"token" : "quick brown fo", "start_offset" : 0, "end_offset" : 15, "type" : "shingle", "position" : 0 },{"token" : "quick brown fox", "start_offset" : 0, "end_offset" : 15, "type" : "shingle", "position" : 0 },{"token" : "b", "start_offset" : 6, "end_offset" : 15, "type" : "shingle", "position" : 1 },{"token" : "br", "start_offset" : 6, "end_offset" : 15, "type" : "shingle", "position" : 1 },{"token" : "bro", "start_offset" : 6, "end_offset" : 15, "type" : "shingle", "position" : 1 },{"token" : "brow", "start_offset" : 6, "end_offset" : 15, "type" : "shingle", "position" : 1 },{"token" : "brown", "start_offset" : 6, "end_offset" : 15, "type" : "shingle", "position" : 1 },{"token" : "brown ", "start_offset" : 6, "end_offset" : 15, "type" : "shingle", "position" : 1 },{"token" : "brown f", "start_offset" : 6, "end_offset" : 15, "type" : "shingle", "position" : 1 },{"token" : "brown fo", "start_offset" : 6, "end_offset" : 15, "type" : "shingle", "position" : 1 },{"token" : "brown fox", "start_offset" : 6, "end_offset" : 15, "type" : "shingle", "position" : 1 },{"token" : "brown fox ", "start_offset" : 6, "end_offset" : 15, "type" : "shingle", "position" : 1 },{"token" : "f", "start_offset" : 12, "end_offset" : 15, "type" : "shingle", "position" : 2 },{"token" : "fo", "start_offset" : 12, "end_offset" : 15, "type" : "shingle", "position" : 2 },{"token" : "fox", "start_offset" : 12, "end_offset" : 15, "type" : "shingle", "position" : 2 },{"token" : "fox ", "start_offset" : 12, "end_offset" : 15, "type" : "shingle", "position" : 2 },{"token" : "fox ", "start_offset" : 12, "end_offset" : 15, "type" : "shingle", "position" : 2 }] }

    這里因為產出的數據太多,所以為了方便并航,做了處理
    至于為什么是這個樣子,還不是很清晰,感覺對于單個詞都增加了一個空格,好奇怪

    比如下面這個樣子的

    POST my_index/_analyze {"field": "my_field._3gram","text": ["quick"]}返回 {"tokens" : [ ] }POST my_index/_analyze {"field": "my_field._index_prefix","text": ["quick"]}返回 {"tokens" : [{"token" : "q", "start_offset" : 0, "end_offset" : 5, "type" : "shingle", "position" : 0 },{"token" : "qu", "start_offset" : 0, "end_offset" : 5, "type" : "shingle", "position" : 0 },{"token" : "qui", "start_offset" : 0, "end_offset" : 5, "type" : "shingle", "position" : 0 },{"token" : "quic", "start_offset" : 0, "end_offset" : 5, "type" : "shingle", "position" : 0 },{"token" : "quick", "start_offset" : 0, "end_offset" : 5, "type" : "shingle", "position" : 0 },{"token" : "quick ", "start_offset" : 0, "end_offset" : 5, "type" : "shingle", "position" : 0 },{"token" : "quick ", "start_offset" : 0, "end_offset" : 5, "type" : "shingle", "position" : 0 }] }

    可以看到也會多出來兩個空格,不知道是干什么用的。

    13. alias 類型:是別的字段的一個別名

    這個就是對一個字段設置別名,感覺作用好像不是很大,這個別名search操作起來和對別名指向的真實field一樣,但是對于index和update操作則是不行的。

    樣例

    PUT trips {"mappings": {"properties": {"distance": {"type": "long"},"route_length_miles": {"type": "alias","path": "distance" },"transit_mode": {"type": "keyword"}}} }PUT trips/_doc/1 {"distance":12345 }PUT trips/_doc/2 {"distance":12 }GET trips/_search {"query": {"range" : {"route_length_miles" : {"lte" : 39}}} }

    14. flattened: 把json類型的復合字段當做一個field進行索引,mapping中不會產生多個字段。

    這個的作用,對于一個對象字需要定一個一個filed mapping,他內部將各個層級個字段處理成了類似keyword進行存儲,這樣就可以用更簡單的方式來進行查詢。
    實際上這個的作用也沒有看太明白。唯一的好處就是防止了mapping爆炸吧。

    使用樣例

    PUT bug_reports {"mappings": {"properties": {"title": {"type": "text"},"labels": {"type": "flattened"}}} }POST bug_reports/_doc/1 {"title": "Results are not sorted correctly.","labels": {"priority": "urgent","release": ["v1.2.5", "v1.3.0"],"timestamp": {"created": 1541458026,"closed": 1541457010}} }POST bug_reports/_search {"query": {"term": {"labels": "urgent"}} }POST bug_reports/_search {"query": {"term": {"labels.release": "v1.3.0"}} }

    這些查詢都能正常使用
    他的使用和keyword有很多相似之處。
    可以支持的查詢有

    term, terms, and terms_set prefix range match and multi_match query_string and simple_query_string exists

    可以設置的mapping param

    boost
    depth_limit
    doc_values
    eager_global_ordinals
    ignore_above
    index
    index_options
    null_value
    similarity
    split_queries_on_whitespace : full text query 是不是應該被空格切分。

    5. Arrays數組類型

    es天然支持了數組類型, 假如是動態類型的話,加入的第一個doc中的當前filed的類型決定了數據的類型,數組中類型要保持一致性。
    像 [ 10, "some string" ]這樣的數據也是會報錯的。

    樣例

    PUT my_index/_doc/1 {"message": "some arrays in this document...","tags": [ "elasticsearch", "wow" ], "lists": [ {"name": "prog_list","description": "programming list"},{"name": "cool_list","description": "cool stuff list"}] }PUT my_index/_doc/2 {"message": "no arrays in this document...","tags": "elasticsearch","lists": {"name": "prog_list","description": "programming list"} }GET my_index/_search {"query": {"match": {"tags": "elasticsearch" }} }

    可以看到第二個文檔不是數組但是還是可以正常的加入進去,所以說es對數組的支持是自然的,主要是因為lucene的設計的支持,lucene將text分成了多個token存儲,所以很方便的可以存儲數組。

    6. 多字段類型支持

    就是說一個字段可以通過不同的存儲方式存進索引,主要是通過mapping param中的 fields 特性來支持

    樣例

    PUT my_index {"mappings": {"properties": {"city": {"type": "text","fields": {"raw": { "type": "keyword"}}}}} }

    總結

    以上是生活随笔為你收集整理的01.elasticsearch-mapping全面解析的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。