<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Elasticsearch從入門(mén)到放棄:瞎說(shuō)Mapping

          共 6943字,需瀏覽 14分鐘

           ·

          2020-08-05 21:36

          前面我們聊了 Elasticsearch 的索引、搜索和分詞器,今天再來(lái)聊另一個(gè)基礎(chǔ)內(nèi)容—— Mapping。

          Mapping 在 Elasticsearch 中的地位相當(dāng)于關(guān)系型數(shù)據(jù)庫(kù)中的 schema,它可以用來(lái)定義索引中字段的名字、定義字段的數(shù)據(jù)類型,還可以用來(lái)做一些字段的配置。從 Elasticsearch 7.0開(kāi)始,Mapping 中不在乎需要定義 type 信息了,具體原因可以看官方的解釋。

          字段的數(shù)據(jù)類型

          我們剛剛提到 Mapping 中可以定義字段的數(shù)據(jù)類型,這可能是 Mapping 最常用的功能了,所以我們先來(lái)看看 Elasticsearch 都支持哪些數(shù)據(jù)類型。

          • 簡(jiǎn)單類型:text、keyword、date、long、double、boolean、ip
          • 復(fù)雜類型:對(duì)象類型、嵌套類型
          • 特殊類型:用于描述地理位置的 geo_point、geo_shape

          Elasticsearch 支持的數(shù)據(jù)類型遠(yuǎn)不止這些,由于篇幅原因,這里就不一一列舉了。我找?guī)讉€(gè)工作中常見(jiàn)的來(lái)介紹一下。

          首先就是字符串了,Elasticsearch 中的字符串有 text 和 keyword 兩種。其中 text 類型的字符串是可以被全文檢索的,它會(huì)被分詞器作用,

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

          在設(shè)置字段類型為 text 時(shí),還可以利用一些參數(shù)對(duì)這個(gè)字段進(jìn)行更進(jìn)一步的定制。

          index:標(biāo)記這個(gè)字段是否能被搜索,默認(rèn)是 true

          search_analyzer:被搜索時(shí)所使用的分詞器,默認(rèn)使用 setting 中設(shè)置的分詞器

          fielddata:字段是否允許在內(nèi)存中進(jìn)行排序、聚合,默認(rèn)是 false

          meta:關(guān)于字段的一些元數(shù)據(jù)

          像一些id、郵箱、域名這樣的字段,我們就需要使用 keyword 類型了。因?yàn)?keyword 類型可以支持排序、聚合,并且只能支持精確查詢。

          有些同學(xué)可能會(huì)把 ID 設(shè)置為數(shù)字類型,這也是沒(méi)問(wèn)題的,數(shù)字類型和 keyword 各有各的好處,使用數(shù)字類型可以進(jìn)行范圍查找,而使用 keyword 類型則有更高的查詢效率。具體用哪種還要看使用場(chǎng)景。

          日期類型在 Elasticsearch 中有三種表現(xiàn)形式

          1. 可以格式化成日期類型的字符串,如"2020-07-26""2015/01/01 12:10:30"這樣的
          2. 毫秒級(jí)時(shí)間戳用 long 類型表示
          3. 秒級(jí)時(shí)間戳用 integer 類型表示

          在 Elasticsearch 內(nèi)部,日期類型是以 long 類型的毫秒級(jí)時(shí)間戳存儲(chǔ)的,時(shí)區(qū)使用的是0時(shí)區(qū)。

          我們可以自定義時(shí)間格式,默認(rèn)使用的是strict_date_optional_time||epoch_millis

          「strict_date_optional_time_nanos」是通用的日期格式解析,至少要包含年份,如果要包含時(shí)間,則用T分隔,例如yyyy-MM-dd'T'HH:mm:ss.SSSSSSZyyyy-MM-dd

          如果想要同時(shí)支持多種日期格式,可以使用format字段

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

          Mapping參數(shù)

          剛才我們提到配置 Mapping 的日期格式的參數(shù)format,Mapping 還提供了很多其他的參數(shù)。

          • analyzer
          • boost
          • coerce
          • copy_to
          • doc_values
          • dynamic
          • eager_global_ordinals
          • enabled
          • fielddata
          • fields
          • format
          • ignore_above
          • ignore_malformed
          • index_options
          • index_phrases
          • index_prefixes
          • index
          • meta
          • normalizer
          • norms
          • null_value
          • position_increment_gap
          • properties
          • search_analyzer
          • similarity
          • store
          • term_vector

          我們來(lái)介紹幾個(gè)常用的字段。

          fields

          首先是fields,它可以使同一個(gè)字段通過(guò)不同的方式實(shí)現(xiàn)不同的目的。

          例如,我們可以對(duì)一個(gè)字符串字段設(shè)置為text類型,用于全文檢索,同時(shí)可以利用fields設(shè)置為keyword類型,用于排序和聚合。

          PUT?my-index-000001
          {
          ??"mappings":?{
          ????"properties":?{
          ??????"city":?{
          ????????"type":?"text",
          ????????"fields":?{
          ??????????"raw":?{
          ????????????"type":??"keyword"
          ??????????}
          ????????}
          ??????}
          ????}
          ??}
          }

          查詢時(shí)我們就可以使用city進(jìn)行全文檢索,使用city.raw進(jìn)行排序和聚合。

          GET?my-index-000001/_search
          {
          ??"query":?{
          ????"match":?{
          ??????"city":?"york"?
          ????}
          ??},
          ??"sort":?{
          ????"city.raw":?"asc"?
          ??},
          ??"aggs":?{
          ????"Cities":?{
          ??????"terms":?{
          ????????"field":?"city.raw"?
          ??????}
          ????}
          ??}
          }

          enabled

          有些時(shí)候,我們只想把某個(gè)字段作為數(shù)據(jù)存儲(chǔ)來(lái)使用,并不需要用來(lái)做搜索,這時(shí),我們就可以將這個(gè)字段禁用掉,字段被禁用以后,它所保存的值也不受 mapping 指定的類型控制。

          PUT?my-index-000001
          {
          ??"mappings":?{
          ????"properties":?{
          ??????"user_id":?{
          ????????"type":??"keyword"
          ??????},
          ??????"last_updated":?{
          ????????"type":?"date"
          ??????},
          ??????"session_data":?{?
          ????????"type":?"object",
          ????????"enabled":?false
          ??????}
          ????}
          ??}
          }

          上面的例子中,我們禁用掉了 session_data 這個(gè)字段,這時(shí),你既可以往 session_data 字段中存儲(chǔ) JSON 格式的數(shù)據(jù),也可以存儲(chǔ)非 JSON 格式的數(shù)據(jù)。

          除了針對(duì)于單個(gè)字段的禁用以外,我們還可以直接禁用掉整個(gè) mapping。我們來(lái)重新創(chuàng)建一個(gè)index

          PUT?my-index-000002
          {
          ??"mappings":?{
          ????"enabled":?false?
          ??}
          }

          這時(shí),文檔所有的字段都不會(huì)被索引,只是用來(lái)存儲(chǔ)。

          需要注意的是,無(wú)論是具體字段中還是整個(gè) mapping 的 enabled 屬性都不可以被修改,因?yàn)橐坏┰O(shè)置為 false,Elasticsearch 就不會(huì)對(duì)字段進(jìn)行索引了,也不會(huì)校驗(yàn)數(shù)據(jù)的合法性,如果產(chǎn)生了臟數(shù)據(jù)以后再設(shè)置為 true,就會(huì)造成程序錯(cuò)誤。

          null_value

          null 在 Elasticsearch 中是不可以被索引或搜索的,這里我們所說(shuō)的 null 并不是狹義上某種語(yǔ)言的 null,而是所有的空值。例如所有值都是 null 的數(shù)組,總之,這里的定義就是沒(méi)有值。

          對(duì)于有需要搜索空值的業(yè)務(wù)怎么辦呢?Elasticsearch 為我們提供了 null_value 這個(gè)參數(shù),它可以指定一個(gè)值,搜索時(shí)使用這個(gè)值來(lái)替代空值。

          舉個(gè)栗子

          PUT?my-index-000001
          {
          ??"mappings":?{
          ????"properties":?{
          ??????"status_code":?{
          ????????"type":???????"keyword",
          ????????"null_value":?"NULL"?
          ??????}
          ????}
          ??}
          }

          我們給 status_code 字段設(shè)置了 null_value"NULL"。這里需要注意, null_value 的類型必須與要查找的數(shù)據(jù)類型相同,如果在這個(gè)例子中 status_code 的類型是long,那么就不能把null_value 設(shè)置為 "NULL"

          dynamic

          對(duì)于新增加的字段:

          • dynamic 設(shè)置為 true 時(shí),一旦有新增字段的文檔寫(xiě)入,Mapping 也會(huì)被更新
          • dynamic 設(shè)置為 false 時(shí),Mapping 不會(huì)被更新,新增字段無(wú)法被索引,但信息會(huì)出現(xiàn)在 _source
          • dynamic 設(shè)置為 strict 時(shí),文檔寫(xiě)入失敗

          對(duì)于已有的字段,一旦已經(jīng)有數(shù)據(jù)寫(xiě)入,就不再支持修改字段定義

          Dynamic Mapping

          我們?cè)趧?chuàng)建索引時(shí),可以不用手動(dòng)寫(xiě) Mappings, Elasticsearch 會(huì)幫我們自動(dòng)識(shí)別出字段的類型。我們稱之為 Dynamic Mapping。不過(guò)有時(shí)推算的可能不是很準(zhǔn)確。

          Elasticsearch 自動(dòng)識(shí)別類型是基于 JSON 的。數(shù)據(jù)類型的對(duì)應(yīng)關(guān)系如下(表格來(lái)自 elastic 官網(wǎng))

          「JSON data type」「Elasticsearch data type」
          nullNo field is added.
          true or falseboolean field
          floating point numberfloat field
          integerlong field
          objectobject field
          arrayDepends on the first non-null value in the array.
          stringEither a date field (if the value passes date detection), a double or long field (if the value passes numeric detection) or a text field, with a keyword sub-field.

          Elasticsearch 支持的字段映射的數(shù)據(jù)類型在這個(gè)文檔中,除了這些,其他的類型映射都需要顯示的指定了。

          關(guān)于日期類型,默認(rèn)是可以映射的,但是 Elasticsearch 只能識(shí)別幾種格式的日期yyyy/MM/dd HH:mm:ss||yyyy/MM/dd||epoch_millis。如果關(guān)掉了 date_detection 開(kāi)關(guān),那么就只能識(shí)別為字符串了。

          PUT?my-index-000001
          {
          ??"mappings":?{
          ????"date_detection":?false
          ??}
          }

          當(dāng)然,你也可以根據(jù)需要自己指定要識(shí)別的日期格式,只需要使用 dynamic_date_formats 參數(shù)即可。

          PUT?my-index-000001
          {
          ??"mappings":?{
          ????"dynamic_date_formats":?["MM/dd/yyyy"]
          ??}
          }

          Elasticsearch 還提供了一種把字符串型的數(shù)字識(shí)別為數(shù)字的能力,它是由 numeric_detection 開(kāi)關(guān)控制的。

          PUT?my-index-000005
          {
          ??"mappings":?{
          ????"numeric_detection":?true
          ??}
          }

          PUT?my-index-000005/_doc/1
          {
          ??"my_float":???"1.0",?
          ??"my_integer":?"1"?
          }

          在這個(gè)例子中,my_float 會(huì)被識(shí)別為 float 類型,而 my_integer 會(huì)被識(shí)別為 long 類型。

          Dynamic template

          dynamic template 允許我們自定義 mapping ,并應(yīng)用到具體索引上。dynamic template 的定義一般是這樣的

          ??"dynamic_templates":?[
          ????{
          ??????"my_template_name":?{?
          ????????...??match?conditions?...?
          ????????"mapping":?{?...?}?
          ??????}
          ????},
          ????...
          ??]

          my_template_name 可以是任意字符串。

          match conditions 包括match_mapping_type, match, match_pattern, unmatch, path_match, path_unmatch 這幾種。

          mapping 就是指匹配到的字段應(yīng)該使用怎樣的 mapping。下面我們介紹幾種 match conditions

          match_mapping_type

          我們先來(lái)看一個(gè)簡(jiǎn)單的例子

          PUT?my-index-000001
          {
          ??"mappings":?{
          ????"dynamic_templates":?[
          ??????{
          ????????"integers":?{
          ??????????"match_mapping_type":?"long",
          ??????????"mapping":?{
          ????????????"type":?"integer"
          ??????????}
          ????????}
          ??????},
          ??????{
          ????????"strings":?{
          ??????????"match_mapping_type":?"string",
          ??????????"mapping":?{
          ????????????"type":?"text",
          ????????????"fields":?{
          ??????????????"raw":?{
          ????????????????"type":??"keyword",
          ????????????????"ignore_above":?256
          ??????????????}
          ????????????}
          ??????????}
          ????????}
          ??????}
          ????]
          ??}
          }

          這里我們有兩個(gè)模版,其一是使用 integer 類型來(lái)代替 long 類型,其二是將字符串類型映射為 keyword

          match 和 unmatch

          這兩個(gè)比較簡(jiǎn)單,match 是指匹配到模式的字段, unmatch 是表示不匹配的字段。

          PUT?my-index-000001
          {
          ??"mappings":?{
          ????"dynamic_templates":?[
          ??????{
          ????????"longs_as_strings":?{
          ??????????"match_mapping_type":?"string",
          ??????????"match":???"long_*",
          ??????????"unmatch":?"*_text",
          ??????????"mapping":?{
          ????????????"type":?"long"
          ??????????}
          ????????}
          ??????}
          ????]
          ??}
          }

          在這個(gè)例子中,我們需要的是 long_ 開(kāi)頭的字符串,不需要 _text結(jié)尾的字符串字段。

          除了以上三種之外,其他的就是 match_pattern 用來(lái)進(jìn)行正則匹配,path_matchpath_unmatch 則是表示字段所在路徑的是否匹配。

          另外 dynamic template 還支持兩種變量替換,分別是 {name}{dynamic_type}。其實(shí) name 就是字段名,dynamic_type 就是檢測(cè)出的字段類型。

          總結(jié)

          關(guān)于 Elasticsearch 的 mapping 我們就先聊這些,我認(rèn)為 mapping 的配置是一個(gè)需要經(jīng)驗(yàn)的事情,當(dāng)你處理的 case 越來(lái)越多之后,就能比較輕松的知道如何更好的配置 mapping 了。此外,mapping 的許多字段和參數(shù)文中都沒(méi)有涉及,對(duì)于我而言,大部分都是用到了現(xiàn)查文檔,不過(guò)也還是建議大家看一看文檔,起碼遇到問(wèn)題時(shí)能知道大概查找文檔的一個(gè)方向。這樣就會(huì)比身邊人強(qiáng)不少。

          往期精彩回顧
          Elasticsearch從入門(mén)到放棄:索引基本使用方法
          Elasticsearch從入門(mén)到放棄:文檔CRUD要牢記
          Elasticsearch從入門(mén)到放棄:分詞器初印象
          Elasticsearch從入門(mén)到放棄:再聊搜索


          瀏覽 57
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  国产精品嫩苞又嫩又紧又爽AV | 国产成人 亚洲 欧洲在线 | 亚洲AV无码成人精品区在线播放 | 欧美啪啪自拍 | 日本三级天天在干 |