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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

03.elasticsearch-mapping-param解析

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

文章目錄

    • 1. mapping param
      • 1. 概覽
      • 2. mapping param詳述
        • 1.1 analyzer
        • 1.2.search_quote_analyzer
        • 2. normalizer
        • 3. boost
        • 4. coerce
        • 5. copy_to
        • 6. doc_values
        • 7. dynamic
        • 8. enabled
        • 9. fielddata
          • 1. fielddata 功能
          • 2.fielddata_frequency_filter
        • 10. eager_global_ordinals
          • 1. 什么是全局序數(shù)
          • 2. global ordinals的load時機
          • 3. global ordinals使用建議
        • 11. format
          • 1. 內(nèi)建format的樣例
          • 2. built-in format
        • 12. ignore_above
        • 13. ignore_malformed
        • 14. index_options
        • 15. index_phrases
        • 16. index_prefixes
        • 17. index
        • 18. fields
        • 19. norms
        • 20. null_value
        • 21. position_increment_gap
        • 22. properties
        • 23. search_analyzer
        • 24. similarity
        • 25. store
        • 26. term_vector

1. mapping param

mapping param 是在定義es中index存儲的doc的某個字段的一些特征的,他決定了該字段的存儲方式以及在存儲之前的analysis部分如何進行。
不同的數(shù)據(jù)類型的field可以設置的mapping param是下面概覽的中的一個子集。在前文中不同的type的field能夠設置的mapping param也是有記錄的。

1. 概覽

  • analyzer
  • normalizer
  • boost
  • coerce
  • copy_to
  • doc_values
  • dynamic
  • enabled
  • fielddata
  • eager_global_ordinals
  • format
  • ignore_above
  • ignore_malformed
  • index_options
  • index_phrases
  • index_prefixes
  • index
  • fields
  • norms
  • null_value
  • position_increment_gap
  • properties
  • search_analyzer
  • similarity
  • store
  • term_vector
  • 2. mapping param詳述

    1.1 analyzer

    這個主要設置的是index的時候首先選擇的analyzer,也是search中中等優(yōu)先使用的analyzer.
    可以參考analyzer相關文章來回顧。
    樣例

    PUT /my_index {"mappings": {"properties": {"text": { "type": "text","fields": {"english": { "type": "text","analyzer": "english"}}}}} }GET my_index/_analyze {"field": "text","text": "The quick Brown Foxes." }GET my_index/_analyze {"field": "text.english","text": "The quick Brown Foxes." }

    1.2.search_quote_analyzer

    不太明白官方在這一個頁面擠進來兩個analyzer,不知道怎么想的,但是為了更好的和官方對應,我也擠一擠好了
    這個analyzer是專門為精準的phrase查詢服務的,也就是針對那些可能有停用詞的phrase查詢。
    如果想要實現(xiàn)精確的phrase查詢,需要在mapping中有這樣的配置

  • analyzer: indexing的時候使用,會包含所有的詞,包括stop words
  • search_analyzer: 非phrase查詢使用,會remove stop words
  • search_quote_analyzer: 針對phrase查詢使用,不會去掉stop words
  • PUT my_index {"settings":{"analysis":{"analyzer":{"my_analyzer":{ "type":"custom","tokenizer":"standard","filter":["lowercase"]},"my_stop_analyzer":{ "type":"custom","tokenizer":"standard","filter":["lowercase","english_stop"]}},"filter":{"english_stop":{"type":"stop","stopwords":"_english_"}}}},"mappings":{"properties":{"title": {"type":"text","analyzer":"my_analyzer", "search_analyzer":"my_stop_analyzer", "search_quote_analyzer":"my_analyzer" }}} }PUT my_index/_doc/1 {"title":"The Quick Brown Fox" }PUT my_index/_doc/2 {"title":"A Quick Brown Fox" }GET my_index/_search {"query":{"query_string":{"query":"\"the quick brown fox\"" }} }

    2. normalizer

    注意,這里不要和后面的norms搞混了,這個也是analysis的一部分。
    只不過他是char_filter 和 token_filter的組合。
    還有就是他可以在keyword類型的字段中使用,會改變dov_values中存儲的值。

    PUT index {"settings": {"analysis": {"normalizer": {"my_normalizer": {"type": "custom","char_filter": [],"filter": ["lowercase", "asciifolding"]}}}},"mappings": {"properties": {"foo": {"type": "keyword","normalizer": "my_normalizer"}}} }PUT index/_doc/1 {"foo": "BàR" }PUT index/_doc/2 {"foo": "bar" }PUT index/_doc/3 {"foo": "baz" }

    使用agg查詢的時候是這樣

    GET index/_search {"size": 0,"aggs": {"foo_terms": {"terms": {"field": "foo"}}} }返回 ..."aggregations": {"foo_terms": {"doc_count_error_upper_bound": 0,"sum_other_doc_count": 0,"buckets": [{"key": "bar","doc_count": 2},{"key": "baz","doc_count": 1}]}}

    這里是因為doc_values中的存儲和_source中對應的字段的值是不一樣的導致的。

    3. boost

    首先說一下,在index的時候指定boost的方式在5.0的時候就已經(jīng)過期了
    在mapping中定義的boost只是在search的時候使用。
    也就是

    PUT my_index {"mappings": {"properties": {"title": {"type": "text","boost": 2 },"content": {"type": "text"}}} }POST _search {"query": {"match" : {"title": {"query": "quick brown fox"}}} }

    的查詢效果和

    POST _search {"query": {"match" : {"title": {"query": "quick brown fox","boost": 2}}} }

    是一致的,主要是用來干預打分。

    4. coerce

    這個屬性是為了處理一些相對來說沒有那么臟的數(shù)據(jù),
    非常臟的數(shù)據(jù),比如type為integer,index的時候給了一個字符串 “abc” ,那么就只能是拋異常,或者是通過設置 ignore_malformed 來忽略對應的字段的dov_values等設置,只是在_source字段中進行存儲。
    沒有那么臟的數(shù)據(jù),比如

  • 定義的type為integer, indexing為 “5” 這種數(shù)字字符串,這種可以輔助進行處理
  • 定義type 為integer, indexing為 5.1 這種,會進行truncate 操作
    注意這個設置只是針對number類型和geometry 類型的數(shù)據(jù)進行處理
  • 定義type為keyword, indexing為 數(shù)字可以成功,這個功勞不是coerce的,后面會看到這個是dynamic mapping的功勞
    實際上在dynamic mapping中也沒有看到,應該是其他類型的往string轉都是直接根據(jù)mapping中的顯式定義轉了

    樣例

    PUT my_index {"aliases" : { },"mappings" : {"properties" : {"requests" : {"type" : "text"},"number":{"type": "integer","coerce":true}}} }PUT my_index/_doc/1 {"requests":"hahaha","number":"5" }PUT my_index/_doc/2 {"requests":"hahaha","number":6.1 }PUT my_index/_doc/3 {"requests":"hahaha","number":7 }GET my_index/_search {"query": {"match_all": {}},"sort": [{"number": {"order": "asc"}}] }

    返回

    {"took" : 1,"timed_out" : false,"_shards" : {"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" : { "requests" : "hahaha", "number" : "5" },"sort" : [ 5 ]},{"_index" : "my_index","_type" : "_doc","_id" : "2","_score" : null,"_source" : { "requests" : "hahaha", "number" : 6.1 },"sort" : [ 6 ]},{"_index" : "my_index","_type" : "_doc","_id" : "3","_score" : null,"_source" : { "requests" : "hahaha", "number" : 7 },"sort" : [ 7 ]}]} }

    從sort字段中可以看出來存儲的對應的doc_values都已經(jīng)發(fā)生了變化了,因為被corces 處理了。
    假如mapping中將corece定義為false,則put操作中的6.1,“5” 都會直接拋異常。

    同時這個設置可以直接在mapping級別進行設置

    PUT my_index {"settings": {"index.mapping.coerce": false},"mappings": {"properties": {"number_one": {"type": "integer","coerce": true},"number_two": {"type": "integer"}}} }

    5. copy_to

    這個是可以設置將多個filed拷貝到一個或者多個其他的field當中。

    PUT my_index {"mappings": {"properties": {"first_name": {"type": "text","copy_to": "last_name" },"last_name": {"type": "text","copy_to": "full_name" },"full_name": {"type": "text"}}} }PUT my_index/_doc/1 {"first_name": "John good boy ","last_name": "Smith bad girl " }GET my_index/_search {"query": {"match": {"full_name": { "query": "smith"}}} }

    上面的文檔會命中put進去的文檔,但是query換成john,good ,boy 中的任意組合都是不能搜索出來的,也就是拷貝會不進行循環(huán),first_name 拷貝到last_name的值不會再拷貝到full_name,只有直接indexing進last_name的值會進入索引。

    假如使用下面的查詢

    GET my_index/_search {"query": {"match": {"last_name": "good"}} }

    也是可以命中該文檔的。
    總的來說,copy_to 有以下特性:

  • 拷貝的是field,不是terms,所以具體產(chǎn)生的terms還是要看目標field的analyzer
  • _source字段不會發(fā)生改變,所以正常返回的文檔中不會不有copy過的內(nèi)容
  • 一個字段可以被拷貝到多個字段,配置的方式是"copy_to": [ "field_1", "field_2" ]
  • 進行遞歸的拷貝是無效的,fa–>fb fb—>fc fa的值并不會被拷貝到fc當中
  • 6. doc_values

    大部分field都進行了indexed操作生成了倒排詞典來查詢,但是進行agg,sort,script_field操作的時候,我們需要快速根據(jù)文檔的編號獲取某個field的值。
    doc_values存儲在磁盤上,在indexing的時候生成,采用列式存儲,獲取對應的field更加快速。除了 analyzed 的字段,doc_values支持其他的大部分常見字段。
    如果這個字段不用來agg,sort,script_field操作,你也可以禁用doc_values來節(jié)約磁盤。

    PUT my_index {"mappings": {"properties": {"status_code": { "type": "keyword"},"session_id": { "type": "keyword","doc_values": false}}} }

    7. dynamic

    默認的情況下doc mapping中的field是可以根據(jù)文檔內(nèi)容動態(tài)增加的,對于object類型的field其子field也是可以動態(tài)增加的。
    其背后就是這個dynamic mapping param在起作用,該字段可以有三個值

  • true : 默認值,新檢測到的field可以添加到mapping當中
  • false: 新檢測到的field會被忽略,不能通過新加入的這個filed進行search操作,但是這個字段還是會出現(xiàn)在_source字段中哦,因為_source就是啥都不管,直接存
  • strict: 新檢測到的field會拋異常,且當前indexing的doc會失敗
  • 在2,3情況下想要正價filed只有修改mapping

    這個字段可以直接在整個mapping級別設置或者為某一個字段設置,采用最近父親生效原則,比如下面的social_networks可以動態(tài)增加field

    PUT my_index {"mappings": {"dynamic": false, "properties": {"user": { "properties": {"name": {"type": "text"},"social_networks": { "dynamic": true,"properties": {}}}}}} }

    8. enabled

    如果對某個field設置了enabled:false該字段不會被index,所以也不能被搜索,也可以對整個mapping設置,這樣的話index的所有字段都是沒有indexed的。

    樣例

    PUT my_index {"mappings": {"properties": {"user_id": {"type": "keyword"},"last_updated": {"type": "date"},"session_data": { "type": "object","enabled": false}}} }PUT my_index/_doc/session_1 {"user_id": "kimchy","session_data": { "arbitrary_object": {"some_array": [ "foo", "bar", { "baz": 2 } ]}},"last_updated": "2015-12-06T18:20:22" }PUT my_index/_doc/session_2 {"user_id": "jpountz","session_data": "none", "last_updated": "2015-12-06T18:22:13" }GET my_index 返回 {"my_index" : {"aliases" : { },"mappings" : {"properties" : {"last_updated" : {"type" : "date"},"session_data" : {"type" : "object","enabled" : false},"user_id" : {"type" : "keyword"}}} }

    首先,這個地方的put session_1 的session_data的內(nèi)容會被忽略,只會存在_source當中,不能被搜索,對應的mapping文件也不會有dynamic field加入。

    對整個mapping設置的樣例

    PUT my_index {"mappings": {"enabled": false } }PUT my_index/_doc/session_1 {"user_id": "kimchy","session_data": {"arbitrary_object": {"some_array": [ "foo", "bar", { "baz": 2 } ]}},"last_updated": "2015-12-06T18:20:22" }GET my_index?flat_settings=true 返回 {"my_index" : {"aliases" : { },"mappings" : {"enabled" : false},"settings" : {"index.creation_date" : "1605509510151","index.number_of_replicas" : "1","index.number_of_shards" : "1","index.provided_name" : "my_index","index.uuid" : "UFZynHQuQl29jg4bFf8mtQ","index.version.created" : "7020099"}} }

    9. fielddata

    1. fielddata 功能

    text field沒有doc_values結構,所以針對text field 的agg,sort ,script操作維護了一個 query-time in-memory 的數(shù)據(jù)結構,這個數(shù)據(jù)結構就叫 fielddata ,
    他會在第一次使用一個text field進行agg,sort,script操作的時候構建的。這個操作耗時耗內(nèi)存,他是通過加載所有的倒排詞典,構建doc->term的正向信息,在jvm中保存這些信息。
    對于text field這個字段默認也是 disabled 的。
    如果非要使用text field進行聚合的話應該使用fields特性新定一個filed 存儲為keyword 使用doc_values特性進行agg, sort,script 操作。

    PUT my_index/_mapping {"properties": {"my_field": { "type": "text","fielddata": true}} }PUT my_index {"mappings": {"properties": {"my_field": { "type": "text","fields": {"keyword": { "type": "keyword"}}}}} }
    2.fielddata_frequency_filter

    為了優(yōu)化fielddata對內(nèi)存的使用,增加了一個2.fielddata_frequency_filter 來選擇性的只加載一些

    PUT my_index {"mappings": {"properties": {"tag": {"type": "text","fielddata": true,"fielddata_frequency_filter": {"min": 0.001,"max": 0.1,"min_segment_size": 500}}}} }

    含有該term的doc的數(shù)量要大于總量的千分之一但是要小于十分之一,segment的doc的數(shù)量大于500才會被加載。

    10. eager_global_ordinals

    1. 什么是全局序數(shù)

    全局序數(shù)主要是為了dov_values類型的數(shù)據(jù)的agg查詢做優(yōu)化的。
    在每個segment當中,對于dov_vlues類型的數(shù)據(jù)存儲做了優(yōu)化,并不是直接存儲doc_id—> field的映射,而是維護了一個segment ordinals mapping,這個mapping的key是一個數(shù)字,這個數(shù)字是怎么來的呢,比如把所有的filed值做字典排序后的序數(shù),或者直接就是賦予一個遞增的integer(去重后),mapping的val是一個keyword(對應的field的value)。這樣的話在doc_values中就只需要存儲doc_id—>(maping中的key)就行了。這樣可以實現(xiàn)數(shù)據(jù)的壓縮,對于重復的字段,在doc_values中就只會存儲一份。
    整個結構類似這樣

    doc_values:
    doc_id—>segment-ordianl
    segment-ordinal—>field-value

    注意,上面講的只是segment ordianals,并不是glabal ordinals。
    global ordinals 就是把當前shard中的所有的segment ordinals 構建為一個全局的 ordinals。
    主要的作用在于使用agg等操作的時候不需要再訪問field的真實值即可進行訪問。對于sort操作不起作用,因為global-ordinal的大小不代表field-value的大小,只能取得field value之后再進行比較。
    所以sort操作只需要segment-ordinals就足夠了,不需要glabal-ordinals

    gobal-ordinals的使用場景

  • keyword,ip,flattened類型字段的agg操作
  • text字段開啟了fielddata之后的agg操作
  • join 字段的has_child查詢或者parent agg 查詢
  • global ordinals的存儲:
    global-ordinals的存儲是在內(nèi)存中構建的,如果內(nèi)存緊張的話也會被 fielddata circuit breaker 給阻斷,而且global-ordinals的內(nèi)存占用可以通過node_stats api獲取,在fielddata項下面。

    2. global ordinals的load時機

    默認的情況下是在第一次需要的query 查詢發(fā)生的時候。如果想保持比較高的index速度,這個方式是很正確的,但是如果對search performance 更在意,應該使用建議開啟eager_global_ordinals 選項,
    當eager_global_ordinals 開啟之后,每當shard 產(chǎn)生了refresh(就是產(chǎn)生了doc的增刪改之后產(chǎn)生新的segment以便于這些內(nèi)容能夠被search),都會重建global ordinals,這會增加indexing的代價但是優(yōu)化查詢單速度。同時開啟這個設置之后再增加副本或者是遷移副本的時候也會eagerly創(chuàng)建global ordianals 。

    在開啟了相關設置之后還可以通過update mapping進行關閉

    PUT my_index/_mapping {"properties": {"tags": {"type": "keyword","eager_global_ordinals": true}} }PUT my_index/_mapping {"properties": {"tags": {"type": "keyword","eager_global_ordinals": false}} }

    對于frozen的index ,global ordianls會在每次查詢的時候創(chuàng)建,在查詢結束后再丟棄,所以eager_global_ordinals 不應該在frozen的index中開啟,同時對于frozen盡量先進行段合并,合并為一個segment最好,這樣就不用創(chuàng)建global ordinals了,因為segment ordinal 和 global ordinal是等價的了。

    3. global ordinals使用建議

    一般情況下,global ordinals 不會暫用太多的內(nèi)存,但是對于有比較大shard的索引或者索引當中有很多term都是uniqued ,load global ordinals 會是一個昂貴的操作。
    還有一些可選的配置來改善global ordinals 的使用

  • 對于terms,smapler,significant_terms 的agg操作支持一個叫 execution_hint 的參數(shù),默認的話是使用 global ordinals 但是可以設置直接使用field-value 進行bucketed 操作
  • 對于不再更新的索引,可以force-merged 成一個segment,這樣的話segment ordinal 和 global ordinal是等價的了。
  • 11. format

    這個主要使用在es對日期類型的數(shù)據(jù)識別上。因為json對日期沒有特殊的支持,只是一個string,所以需要進行特殊識別才行。

    這個format分為兩種,一種是es內(nèi)建的format,支持用戶通過名稱進行快速的選配,還有一種是自定義的format,只要符合java中java.time.format.DateTimeFormatter 中定義的規(guī)范的string格式都可以

    1. 內(nèi)建format的樣例
    PUT my_index {"mappings": {"properties": {"date": {"type": "date","format": "yyyy-MM-dd"}}} }
    2. built-in format

    epoch_millis: Java Long.MIN_VALUE and Long.MAX_VALUE.
    epoch_second: Java Long.MIN_VALUE and Long.MAX_VALUE.除以1000,標識的范圍和上一個保持一致
    date_optional_time or strict_date_optional_time: iso標準時間定義
    basic_date: yyyyMMdd
    basic_date_time: yyyyMMdd’T’HHmmss.SSSZ
    basic_date_time_no_millis: yyyyMMdd’T’HHmmssZ
    basic_ordinal_date: yyyyDDD
    basic_ordinal_date_time: yyyyDDD’T’HHmmss.SSSZ
    basic_ordinal_date_time_no_millis: yyyyDDD’T’HHmmssZ
    basic_time: HHmmss.SSSZ
    basic_time_no_millis: HHmmssZ
    basic_t_time: 'T’HHmmss.SSSZ
    basic_t_time_no_millis: 'T’HHmmssZ
    basic_week_date or strict_basic_week_date: xxxx’W’wwe
    basic_week_date_time or strict_basic_week_date_time: xxxx’W’wwe’T’HHmmss.SSSZ
    basic_week_date_time_no_millis or strict_basic_week_date_time_no_millis: xxxx’W’wwe’T’HHmmssZ
    date or strict_date: yyyy-MM-dd
    date_hour or strict_date_hour: yyyy-MM-dd’T’HH
    date_hour_minute or strict_date_hour_minute: yyyy-MM-dd’T’HH:mm
    date_hour_minute_second or strict_date_hour_minute_second: yyyy-MM-dd’T’HH:mm:ss
    date_hour_minute_second_fraction or strict_date_hour_minute_second_fraction: yyyy-MM-dd’T’HH:mm:ss.SSS
    date_hour_minute_second_millis or strict_date_hour_minute_second_millis: yyyy-MM-dd’T’HH:mm:ss.SSS
    date_time or strict_date_time: yyyy-MM-dd’T’HH:mm:ss.SSSZZ
    date_time_no_millis or strict_date_time_no_millis: yyyy-MM-dd’T’HH:mm:ssZZ
    hour or strict_hour: HH
    hour_minute or strict_hour_minute: HH:mm.
    hour_minute_second or strict_hour_minute_second: HH:mm:ss
    hour_minute_second_fraction or strict_hour_minute_second_fraction: HH:mm:ss.SSS
    hour_minute_second_millis or strict_hour_minute_second_millis: HH:mm:ss.SSS
    ordinal_date or strict_ordinal_date: yyyy-DDD
    ordinal_date_time or strict_ordinal_date_time: yyyy-DDD’T’HH:mm:ss.SSSZZ
    ordinal_date_time_no_millis or strict_ordinal_date_time_no_millis: yyyy-DDD’T’HH:mm:ssZZ
    time or strict_time: HH:mm:ss.SSSZZ
    time_no_millis or strict_time_no_millis: HH:mm:ssZZ
    t_time or strict_t_time: 'T’HH:mm:ss.SSSZZ
    t_time_no_millis or strict_t_time_no_millis: 'T’HH:mm:ssZZ
    week_date or strict_week_date: xxxx-'W’ww-e
    week_date_time or strict_week_date_time: xxxx-'W’ww-e’T’HH:mm:ss.SSSZZ
    week_date_time_no_millis or strict_week_date_time_no_millis: xxxx-'W’ww-e’T’HH:mm:ssZZ
    weekyear or strict_weekyear: xxxx
    weekyear_week or strict_weekyear_week: xxxx-'W’ww
    weekyear_week_day or strict_weekyear_week_day: xxxx-'W’ww-e
    year or strict_year: yyyy
    year_month or strict_year_month: yyyy-MM
    year_month_day or strict_year_month_day: yyyy-MM-dd

    es真是太寶媽了,但是估計大部分人都沒有耐心看完這些吧😭

    12. ignore_above

    對string類型的數(shù)據(jù)起作用,是一個int值,長度超過這個值的string不會被 indexed或者stored(field store),對于string arr ,限制會應用到其中的每一個元素。但是對于那些超過長度的字段仍然會在_source字段中進行存儲。
    這個測試是對keyword類型的起作用,text類型的不允許設置這個參數(shù)。

    PUT my_index {"mappings": {"properties": {"message": {"type": "keyword","ignore_above": 20 }}} }PUT my_index/_doc/1 {"message": "Syntax error" }這個也會put成功,但是doc_values不會被存儲 PUT my_index/_doc/2 {"message": "Syntax error with some long stacktrace" }GET my_index/_search {"aggs": {"messages": {"terms": {"field": "message"}}} }

    在查詢中會返回所有的文檔,但是agg的結果沒有第二個文檔

    13. ignore_malformed

    這個設置對很多字段都生效,會忽略格式上不合法的字段,但是整個doc依然能夠成功indexed,不合法的字段在_source字段依然會有存儲,但是沒有doc_value等信息的存儲了。
    如果這個指端設置為false(默認值),出現(xiàn)不合法的寫入之后會拋異常,整個文檔也沒有辦法正常寫入。

    樣例

    PUT my_index {"mappings": {"properties": {"number_one": {"type": "integer","ignore_malformed": true},"number_two": {"type": "integer"}}} }會成功 PUT my_index/_doc/1 {"text": "Some text value","number_one": "foo" }拋異常 PUT my_index/_doc/2 {"text": "Some text value","number_two": "foo" }

    還可以在index級別設置這個值

    PUT my_index {"settings": {"index.mapping.ignore_malformed": true },"mappings": {"properties": {"number_one": { "type": "byte"},"number_two": {"type": "integer","ignore_malformed": false }}} }

    同樣的,對于malformed的字段會有所記錄,在doc中增加一個 _ignored字段進行標識。

    對于object,nested,range 類型的字段沒有辦法設置這個屬性

    14. index_options

    這個屬性主要是針對string.text的字段進行設置的。
    主要設置了哪些信息會被加入到倒排索引當中。
    可以是下面的幾個值

  • docs: 只有doc number 被加入,只能回答當前doc的這個field是否包含這個term
  • freqs: doc-number + term-frequencies ,就是這個term在當前field中出現(xiàn)的頻次,可以用來計算score
  • positions: doc-numer + term-frequencies + term-position position可以用來做phrase或者距離查詢 ()
  • offsets: doc-numer + term-frequencies + term-position+ character-offsets offsets 包含了term中在原始的string中的字符級別的位置,可以用來加速高亮顯示
  • 對于string.text positions 是默認的設置
    對于其他可以設置的字段 docs是默認的設置

    對于numeric 類型的數(shù)據(jù)不支持這個屬性

    PUT my_index {"mappings": {"properties": {"text": {"type": "text","index_options": "offsets"}}} }PUT my_index/_doc/1 {"text": "Quick brown fox" }GET my_index/_search {"query": {"match": {"text": "brown fox"}},"highlight": {"fields": {"text": {} }} }

    15. index_phrases

    這個是為了優(yōu)化phrase查詢而做的設置,設置了true,會假如一個2gram的shingles filter的功能,會把兩個term結合到一起產(chǎn)生新的field.
    這會讓phrase queries 運行的更加高效,但是index的存儲占用也會變大,而且在沒有stop-word的工作的更好,因為有stop-word的查詢會退化為一個普通的phrase query
    默認值為false

    16. index_prefixes

    這個允許index term的前綴來加快前綴查詢匹配的速度。
    有兩個參數(shù)

  • min_chars : 前綴最少的字符數(shù)
  • max_chars : 最大的前綴長度
  • PUT my_index {"mappings": {"properties": {"full_name": {"type": "text","index_prefixes": {"min_chars" : 1,"max_chars" : 10}}}} }

    這個不知道怎么進行驗證,后面看看吧

    17. index

    這個就是設置字段是否indexed, 對應值為false的字段不能被搜索,默認為true

    18. fields

    這個屬性主要是為了支撐一個field多種存儲類型的需求

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

    兩個字段可以有不同個type,不同的analyzer等

    19. norms

    這個是存儲各種各樣的normalization factors 歸一化系數(shù),這些系數(shù)是為了能夠在query的時候計算出相似度score使用
    盡管norms對計算相似度打分很有用,但是也會占據(jù)不少存儲空間,正常情況下,index的每個文檔中的每個field都會占用一個byte,即使某個doc中沒有這個field也會占用(這是lucene的存儲原理決定的),所以如果你不需要對一個field進行score計算時可以針對這個field關閉這個選項。
    這個mapping param 從able變成 disable 可以通過PUT mapping api進行修改,但是無法再從disable變成able

    PUT my_index/_mapping {"properties": {"title": {"type": "text","norms": false}} }

    update 成false之后不會立即移除norms存儲,會在old segment合并生成新的segment的時候去除norms信息

    20. null_value

    正常情況下,null值被認為該字段沒有值,所以該doc的該字段不會被indexed,也不可searchable
    null_value 的設置可以在該field indexing的值為null的時候放入一個特殊值,這個值可以進行indexed和searchable,需要注意的是該字段必須被設置為null,如果index的時候不傳該字段的話則也不會被替換成null_value的值
    當然,該字段同樣不會修改_source字段

    樣例

    PUT my_index {"mappings": {"properties": {"status_code": {"type": "keyword","null_value": "NULL" }}} }PUT my_index/_doc/1 {"status_code": null }PUT my_index/_doc/2 {"status_code": [] }PUT my_index/_doc/3 {“message”:"this is message" }GET my_index/_search {"query": {"term": {"status_code": "NULL" }} }

    對于查詢而要,doc 1 會被召回,doc2 ,doc3不會被召回,doc3是因為沒有顯式的指定該字段的值為null。

    21. position_increment_gap

    這個mapping param主要用在string.text字段,而且是當該field 的value是一個數(shù)組的時候才會起作用。
    正常情況下一個text輸入field之前會進行analysis,一般會有ananlzyer分詞,并且記錄每個詞的position,當一個filed的輸入有多個values的時候,在這些values之間實際上是不應該有position信息的,所以一旦這樣的輸入出現(xiàn),會填充虛假的gap,讓不同的field之間的position加大。

    觀察下面的analyze

    POST my_index/_analyze {"analyzer": "standard","text": ["want some","like bread"] }{"tokens" : [{"token" : "want","start_offset" : 0,"end_offset" : 4,"type" : "<ALPHANUM>","position" : 0},{"token" : "some","start_offset" : 5,"end_offset" : 9,"type" : "<ALPHANUM>","position" : 1},{"token" : "like","start_offset" : 10,"end_offset" : 14,"type" : "<ALPHANUM>","position" : 102},{"token" : "bread","start_offset" : 15,"end_offset" : 20,"type" : "<ALPHANUM>","position" : 103}] }

    可以看到 like bread的position 一個是102,一個是103,這就說明中間加入了虛假的gap,因為中間的position實際上是沒有詞的。
    gap 的值 就是由position_increment_gap 設置的,默認是100
    這種操作主要是為了在進行phrase查詢的時候出錯。
    比如查詢some like命中了該文檔是不合理的。

    比如下面的案例

    PUT my_index {"mappings": {"properties": {"names": {"type": "text","position_increment_gap": 0 }}} }PUT my_index/_doc/1 {"names": [ "John Abraham", "Lincoln Smith"] }GET my_index/_search {"query": {"match_phrase": {"names": "Abraham Lincoln" }} }

    該查詢會將doc1召回,顯然是不合理的。

    22. properties

    mapping中的 object fields 和 nested fields 包含properties屬性,這個屬性可以是任何數(shù)據(jù)類型,包括object和nested類型

    properties可以通過三種方式設置

  • 創(chuàng)建index的時候設置
  • update index mapping (使用put mapping api)
  • 根據(jù)indexing的doc動態(tài)的生成
  • PUT my_index {"mappings": {"properties": { "manager": {"properties": { "age": { "type": "integer" },"name": { "type": "text" }}},"employees": {"type": "nested","properties": { "age": { "type": "integer" },"name": { "type": "text" }}}}} }PUT my_index/_doc/1 {"region": "US","manager": {"name": "Alice White","age": 30},"employees": [{"name": "John Smith","age": 34},{"name": "Peter Brown","age": 26}] }

    這些子屬性可以通過點號.來再query或者agg中引用。

    GET my_index/_search {"query": {"match": {"manager.name": "Alice White"}},"aggs": {"Employees": {"nested": {"path": "employees"},"aggs": {"Employee Ages": {"histogram": {"field": "employees.age","interval": 5}}}}} }

    23. search_analyzer

    一般情況下,會在indexing和query的時候使用相同的analyzer 來保持分詞使用的一致性。
    但是有些時候我們也可以在index和query的時候使用不同的analyzer來達到更好的搜索效果,比如,對于著名的中文分詞器 ik-analyzer 插件,
    在index的時候我們一般使用 ik_max_wordanalyzer 來產(chǎn)生盡可能多的詞匯以便于在搜索的時候使用
    在query的時候我們一般使用 ik_smart產(chǎn)生最佳分詞(不是最多的,可能是按照最有意義的分詞方式)這樣的命中效果會更好一些,防止召回的太多。
    又或者使用edge_ngram進行indexing分詞,在query的時候使用standard,可以實現(xiàn)前綴匹配

    PUT my_index {"settings": {"analysis": {"filter": {"autocomplete_filter": {"type": "edge_ngram","min_gram": 1,"max_gram": 20}},"analyzer": {"autocomplete": { "type": "custom","tokenizer": "standard","filter": ["lowercase","autocomplete_filter"]}}}},"mappings": {"properties": {"text": {"type": "text","analyzer": "autocomplete", "search_analyzer": "standard" }}} }PUT my_index/_doc/1 {"text": "Quick Brown Fox" }GET my_index/_search {"query": {"match": {"text": {"query": "Quick Br", "operator": "and"}}} }

    24. similarity

    這個主要用來設置es的string.text查詢的相似度計算模型
    這個計算模型可以自定義,也可以使用es內(nèi)置的開箱即用,一般情況下內(nèi)建的開箱即用就可以滿足大部分需求,如果采用自定義的方式需要對相似度計算的模型比較熟悉才好操作。在后面介紹相似度模型的時候會重點再介紹es中有哪些相似度計算模型,這里只是著重說一下使用es內(nèi)置的如果和配置。

    es內(nèi)置的相似度打分模型有3個

  • BM25 : es中默認的打分模型
  • classic: es早起版本的打分模型,也是經(jīng)典的打分模型
  • boolean: 只能判斷是否命中,得分score就是query boost
  • PUT my_index {"mappings": {"properties": {"default_field": { "type": "text"},"boolean_sim_field": {"type": "text","similarity": "boolean" }}} }

    關于BM25的discount_overlaps 的一個比較好的解釋
    https://stackoverflow.com/questions/44115497/elasticsearch-similarity-discount-overlaps

    25. store

    正常情況下field會被indexed,可以被search,整個doc的內(nèi)容都會被存儲到_source字段,
    但是這個字段的原始值不會被單獨存儲,如果只想獲取這個字段的原始值的話需要通過source filtering

    PUT my_index {"mappings": {"properties": {"title": {"type": "text","store": true },"date": {"type": "date","store": true },"content": {"type": "text"}}} }PUT my_index/_doc/1 {"title": "Some short title","date": "2015-01-01","content": "A very long content field..." }GET my_index/_search {"stored_fields": [ "title", "date" ] }

    返回

    "hits" : [{"_index" : "my_index","_type" : "_doc","_id" : "1","_score" : 1.0,"fields" : {"date" : ["2015-01-01T00:00:00.000Z"],"title" : ["Some short title"]}}]

    同樣的,我們也可以這樣使用

    GET my_index/_search {"_source": ["title","date"] }返回 hits" : [{"_index" : "my_index","_type" : "_doc","_id" : "1","_score" : 1.0,"_source" : {"date" : "2015-01-01","title" : "Some short title"}}]

    一般情況下沒有必要的話不要開啟這個屬性,只有在doc中有某些field的內(nèi)容非常大,而有些查詢不需要的那些大內(nèi)容的field的時候才建議對小內(nèi)容的field使用store屬性。

    26. term_vector

    term向量是string.text類型的數(shù)據(jù)進行了analysis處理后的產(chǎn)生的term的組合。
    他包含了下面的內(nèi)容

  • 一個terms的list
  • 每個term中的position
  • 每個term在原始文檔中的offset
  • payload 信息
  • term_vector 的設置可以有

    no: No term vectors are stored. (default) 這個是默認值

    yes: Just the terms in the field are stored.

    with_positions: Terms and positions are stored.

    with_offsets: Terms and character offsets are stored.

    with_positions_offsets: Terms, positions, and character offsets are stored.

    with_positions_payloads: Terms, positions, and payloads are stored.

    with_positions_offsets_payloads: Terms, positions, offsets and payloads are stored.

    當我們使用term vectors API的時候可以查看一個文檔中field的vector

    樣例

    PUT my_index {"mappings": {"properties": {"text": {"type": "text","term_vector": "with_positions_offsets"},"number":{"type": "text"}}} }PUT my_index/_doc/1?refresh {"text": "Quick brown fox","number":"want app and want banana" }

    使用terms vectors api查看field包含的terms

    GET my_index/_termvectors/1?fields=number,text返回{"_index" : "my_index","_type" : "_doc","_id" : "1","_version" : 1,"found" : true,"took" : 0,"term_vectors" : {"text" : {"field_statistics" : {"sum_doc_freq" : 3,"doc_count" : 1,"sum_ttf" : 3},"terms" : {"brown" : {"term_freq" : 1,"tokens" : [ { "position" : 1, "start_offset" : 6, "end_offset" : 11}]},"fox" : {"term_freq" : 1,"tokens" : [ { "position" : 2, "start_offset" : 12, "end_offset" : 15}]},"quick" : {"term_freq" : 1,"tokens" : [ { "position" : 0, "start_offset" : 0, "end_offset" : 5}]}}},"number" : {"field_statistics" : {"sum_doc_freq" : 4,"doc_count" : 1,"sum_ttf" : 5},"terms" : {"and" : {"term_freq" : 1,"tokens" : [ { "position" : 2, "start_offset" : 9, "end_offset" : 12}]},"app" : {"term_freq" : 1,"tokens" : [ { "position" : 1, "start_offset" : 5, "end_offset" : 8}]},"banana" : {"term_freq" : 1,"tokens" : [ { "position" : 4, "start_offset" : 18, "end_offset" : 24}]},"want" : {"term_freq" : 2,"tokens" : [ { "position" : 0, "start_offset" : 0, "end_offset" : 4}, { "position" : 3, "start_offset" : 13, "end_offset" : 17}]}}}} }

    以上,可以看到文檔的term vector信息,為什么number字段沒有設置保存term_vector 在使用api的時候依然能夠查到呢,這是因為terms vector api的原理導致的,如果沒有的話他會自己從index中進行計算得到數(shù)據(jù)

    假如直接使用

    GET my_index/_termvectors/1

    這個只會獲取默認已經(jīng)存儲的term vectors,那么就不會返回number的term vectors了。

    使用

    GET my_index/_termvectors/1?fields=number,text

    會觸發(fā)強制計算term vectors。
    這個一般情況下沒有什么用,只是在快速高亮顯示上又一些用處。

    而且term_vector設置到with_positions_offsets 就會使這個字段在索引中的存儲翻倍,因為需要一個額外的list terms去維護。

    總結

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

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。