<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>

          如何設(shè)計一個高性能 Elasticsearch mapping

          共 7738字,需瀏覽 16分鐘

           ·

          2021-05-30 08:51

          點擊上方藍色字體,選擇“標(biāo)星公眾號”

          優(yōu)質(zhì)文章,第一時間送達

            作者 |  lonely-wolf

          來源 |  urlify.cn/6NB7Fb

          前言

          在關(guān)系型數(shù)據(jù)庫設(shè)計當(dāng)中,表的設(shè)計尤其重要,然而關(guān)系型數(shù)據(jù)庫更關(guān)注的表與表之間的關(guān)系,以及表的劃分是否合理,而 Elasticsearch 中卻更加關(guān)注字段類型的設(shè)計,一個好的字段類型設(shè)計可以更好的利用 Elasticsearch 的搜索分析特性。

          mapping

          如果說我們想要用好 Elasticsearch,那么就必須要先了解 mapping 什么是 mapping。一句話:mapping是定義如何存儲和索引文檔及其包含的字段的過程。

          mapping 能做什么

          前面我們提到,在 Elasticsearch 中,mapping 類似于傳統(tǒng)關(guān)系型數(shù)據(jù)庫的表結(jié)構(gòu)定義,主要做以下幾件事:

          • 定義字段名稱和字段類型。

          • 定義倒排索引相關(guān)的配置,比如是否被索引,是否可以被分詞等。

          mapping 可以分為兩種:Dynamic mapping 和 Explicit mapping

          Dynamic mapping

          Dynamic mapping 即:動態(tài)映射。動態(tài)映射顧名思義就是 mapping 會被動態(tài)創(chuàng)建,也就是說我們不需要定義 mapping 就可以往一個索引插入數(shù)據(jù),插入索引數(shù)據(jù)之后,Elasticsearch 會根據(jù)插入的數(shù)據(jù)自動推測數(shù)據(jù)類型,進而動創(chuàng)建 mapping

          比如下面就是往一個不存在的索引 index_001 插入一條數(shù)據(jù):

          PUT index_001/_doc/1
          {
            "name":"lonely wolf",
            "age": 18,
            "create_date":"2021-05-19 20:45:11",
            "update_date":"2021-05-23"
          }

          插入數(shù)據(jù)之后,執(zhí)行 GET index_001 來查詢一下索引信息:

          可以發(fā)現(xiàn),這時候索引已經(jīng)被自動創(chuàng)建了,而且 age 字段被 Elasticsearch 定義為 long 類型,update_date 被定義為 data 類型,其他兩個字段則被推測為 text 類型。

          Elasticsearch 中自動映射類型規(guī)則可以通過 dynamic 參數(shù)進行配置,dynamic 類型有 4 種:

          dynamic=true

          默認(rèn)值。當(dāng)設(shè)置為 true 時,一旦有新字段插入文檔,則 mapping 會被同步更新。

          我們在上面的文檔中再插入一個新文檔,新文檔新增一個 address 字段:

          PUT index_001/_doc/2
          {
            "name":"lonely wolf2",
            "age": 20,
            "create_date":"2021-05-23 11:37:11",
            "update_date":"2021-05-23",
            "address":"廣東深圳"
          }

          然后再查看一下 mapping,可以看到 mapping 已經(jīng)新增了一個 address 字段,mapping 字段被更新意味著該字段會加入索引:

          dynamic=runtime

          這個類型和 true 類型非常相似,但是有一個非常大的區(qū)別就是,雖然加入新字段也會更新 mapping,但是新加入的字段不會被索引,也就是不會使得索引變大,不過雖然不被索引,但是新加入的字段依然可以被查詢,只是查詢的代價會更大。所以這種類型一般不建議用在經(jīng)常查詢的條件字段上,而更適合用在一些不確定數(shù)據(jù)結(jié)構(gòu)的日志類索引中。

          修改 dynamic 類型:

          PUT index_001/_mapping
          {
            "dynamic":  "runtime"
          }

          新增一個文檔,并加入一個新字段:

          PUT index_001/_doc/3
          {
            "email":"[email protected]"
          }

          最后詢一下 mapping,可以看到字段屬性是 runtime,而且類型是 keyword

          下表就是自動創(chuàng)建 mapping 時,Elasticsearch 的映射關(guān)系:

          插入數(shù)據(jù)類型dynamic=truedynamic=runtime
          null不會添加任何字段不會添加任何字段
          true 或 falsebooleanboolean
          doublefloatdouble
          integerlonglong
          objectobjectobject
          string(通過 date 校驗)datedate
          string(通過 numreic 校驗)float 或 longdouble 或 long
          string(沒有通過 date 或 numreic 校驗)text ,并且同時會創(chuàng)建一個 keyword 子域keyword
          array取決于數(shù)組中第一個非 null 值取決于數(shù)組中第一個非 null 值

          PS:keyword 表示 不參與分詞。

          dynamic=false

          當(dāng)設(shè)置為 false 時,新加入的字段不會被更新到 mapping,也就是說新字段不會被索引,故以這個字段為條件進行搜索時,無法被搜索到(這一點要注意和 runtime 類型進行區(qū)分),不過雖然無法被索引,但是該字段會出現(xiàn)在 _source 中。也就是說該字段不能作為查詢條件,但是能被查詢出來

          接下來我們將 dynamic 修改為 false,并新增一個字段來驗證,可以發(fā)現(xiàn)新增的字段會出現(xiàn)在 _source 中,但是無法作為條件被查詢出來:

          dynamic=strict

          這種類型最為嚴(yán)格,表示不允許新增一個不在 mapping 中的字段,一旦新增的字段不在 mapping 定義中,則直接報錯:

          是否可以修改 mapping 中的數(shù)據(jù)類型

          在 Elasticsearch 中,一旦一個字段被定義在了 mapping 中,是無法被修改的,因為一旦字段被修改了,就會無法被索引(新增字段除外),所以一般我們需要修改索引的話,都會重建索引,并采用 reindex 操作來遷移數(shù)據(jù)。

          關(guān)閉 dynamic mapping

          可以通過以下兩個配置來關(guān)閉 dynamic mapping,以下兩個屬性默認(rèn)值均為 true,如果需要關(guān)閉,則需要修改為 false

          action.auto_create_index: true
          index.mapper.dynamic: true

          Explicit mapping

          Explicit mapping 即:顯式映射。也就是說這時候我們需要顯示的定義字段類型。

          Elasticsearch 中支持的字段類型很多,在這里就舉一些比較常用的字段類型:

          text 類型

          這是最常用的一種類型,存儲字符串,用于全文索引。當(dāng)字段被定義為 text 類型時,默認(rèn)不能用于聚合,排序等操作:

          可以看到,用 text 類型字段排序匯報湊,如果想要允許這些操作,可以通過設(shè)置 fielddata=true,如下

          PUT my-index-011/_mapping
          {
            "properties": {
              "my_field": { 
                "type":     "text",
                "fielddata"true
              }
            }
          }

          field 字段存儲在堆內(nèi)存中,因為其涉及到的計算比較消耗性能,所以一般不建議設(shè)置 fielddata=true,而是通過建立一個 keyword 子域來實現(xiàn)(默認(rèn)方式):

          PUT index_111
          {
            "mappings": {
              "properties": {
                "my_field": { 
                  "type""text",
                  "fields": {
                    "keyword": { 
                      "type""keyword"
                    }
                  }
                }
              }
            }
          }

          這種定義方式我們可以將一個字段同時作為 text 和 keyword 類型使用,如果要用于聚合或者排序等操作則可以使用 字段名.keyword 來作為字段名來進行操作:

          keyword 類型

          這種類型也非常常用,該字段存儲的數(shù)據(jù)表示一個整體,不可被分詞,所以一般不會用來定義大本文的全文檢索字段,而是用來存儲一些結(jié)構(gòu)化的字符串,比如:id,郵箱,標(biāo)簽等。

          keyword 類型一般用于聚合,排序等操作。除此之外,該字段還有兩種衍生類型:constant_keyword 和 wildcard

          • constant_keyword:一般用于定義常量類型,比如一個索引中某一個字段全部為同一個值,可以定義為這種類型。

          • wildcard:一般用于模糊匹配查詢或者正則匹配查詢。

          如下就是一個模糊匹配查詢的示例(可以配合通配符使用,類似于關(guān)系型數(shù)據(jù)庫的 like 操作):

          GET index_112/_search
          {
            "query": {
              "wildcard": {
                "my_wildcard": {
                  "value""*quite*lengthy"
                }
              }
            }
          }

          date 類型

          用于定義日期類型,定義日期類型的同時,可以通過 format 來指定日期的格式:

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

          numeric 類型

          Elasticsearch 中提供了比較多的格式用來表示不同長度的數(shù)字類型:

          數(shù)字類型長度
          long64 位有符號整數(shù)。范圍:-2 的 63 次方到 2 的 63 次方 -1
          integer32 位有符號整數(shù)。范圍:-2 的 31 次方到 2 的 31 次方 -1
          short16 位有符號整數(shù)。范圍:-32768 到 32767
          byte8 位有符號整數(shù)。范圍:-128 到 127
          double64 位雙精度小數(shù)
          float32 位單精度小數(shù)
          half_float16 位單精度小數(shù)
          scaled_float帶有縮放因子的浮點數(shù),一般適用于存放金額之類的數(shù)據(jù)。比如 18.88 元,縮放因子是 100,那么在索引時會被索引為 1888(即:原值 * 縮放因子)
          unsigned_long64 位無符號整數(shù)。范圍:0 到 2 的 64 次方減 1

          定義方式如下所示:

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

          boolean 類型

          布爾類型比較簡單,只有 true 和 false 兩種:

          PUT index_001
          {
            "mappings": {
              "properties": {
                "is_published": {
                  "type""boolean"
                }
              }
            }
          }

          其他類型

          除了上面介紹的一些比較常用的數(shù)據(jù)類型,Elasticsearch 中還有一些高級數(shù)據(jù)類型:如 Nested(嵌套類型),地理數(shù)據(jù)類型,ip 類型等。

          總結(jié)

          Elasticsearch 中支持動態(tài) mapping 和顯示 mapping 兩種,在使用中有時候可以先插入一條數(shù)據(jù)到臨時索引,等自動生成 mapping 之后,在對現(xiàn)有 mapping 進行修改調(diào)整,在字段上尤其要考慮好 text 類型和 keyword 類型的設(shè)置,如果需要支持全文搜索和分詞搜索,則需要使用 text 類型,需要支持關(guān)鍵字模糊搜索或者聚合排序等操作可以考慮使用 keyword 字段。






          瀏覽 52
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <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>
                  欧美黄网站在线观看 | 欧美福利第一页 | 日韩中文字幕A | 影音先锋成人 | 91香蕉网站在线下载 |