<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 有沒有比 reindex 更輕量級的更換字段類型的方式?

          共 8281字,需瀏覽 17分鐘

           ·

          2022-06-17 16:31


          1、線上實戰(zhàn)環(huán)節(jié)遇到問題

          現(xiàn)在有一組數(shù)據(jù),其中 resultChar 是 keyword 類型,但其中有數(shù)字也有字符串,請問怎么能在大于小于查詢的時候?qū)⑵渲械臄?shù)字按照數(shù)字的類型進行大于小于的查詢,結(jié)構(gòu)如下:

          {
              "lisCheckItemList": [
                  {
                      "resultChar""1",
                      "itemName""項目1"
                  },
                  {
                      "resultChar""2",
                      "itemName""項目2"
                  },
                  {
                      "resultChar""11",
                      "itemName""項目3"
                  },
                  {
                      "resultChar""22",
                      "itemName""項目4"
                  },
                  {
                      "resultChar""25",
                      "itemName""項目"
                  },
                  {
                      "resultChar""3",
                      "itemName""項目5"
                  },
                  {
                      "resultChar""陰性",
                      "itemName""項目6"
                  }
              ]
          }

          結(jié)果:如果查詢 resultChar 大于 2 的數(shù)據(jù)的話目前不會查詢出 resultChar 為 11 的數(shù)據(jù),因為現(xiàn)在的 resultChar 類型為 keyword .但是因為 resultChar 里面有數(shù)字也有字符所以不可以使用數(shù)字的類型.請問有什么方法可以將 keyword 類型中的數(shù)字按照數(shù)字類型進行大于小于查詢.

          期待結(jié)果: 查詢 resultChar 大于 2的數(shù)據(jù)時會過濾掉小于 2 的并查詢出大于 2 的數(shù)據(jù)(查詢出 resultChar 為陰性的那個數(shù)據(jù)也可以,只要數(shù)字的查詢是對的就可以)

          問題來源:Elasticsearch 中文社區(qū)

          https://elasticsearch.cn/question/12809

          2、問題拆解

          2.1 發(fā)現(xiàn)問題:數(shù)據(jù)建模不合理

          對于 resultchar 字段來說,這個字段前面幾個值都是數(shù)值加了引號的字符串類型,后面是“陰性”。MySQL 有數(shù)據(jù)完整性這一說,要求相同字段的語義是合理的,沒有歧義的,是相容的。

          Elasticsearch 雖沒有類似的完整性說明。這種寫入數(shù)據(jù)方式,從 Elasticsearch 角度來看,沒有問題,都是字符串。但是,從業(yè)務(wù)層面來看,這帶來后來處理的不確定性和麻煩。

          一句話,這種建模方式有“百害”而無一利。建議從業(yè)務(wù)角度出發(fā),及時止損。嚴格遵守數(shù)據(jù)建模規(guī)范理論,重新建模,數(shù)據(jù)寫入更加符合業(yè)務(wù)邏輯,從根源上解決這個問題。

          2.2 問題本質(zhì)

          將:resultChar 類型轉(zhuǎn)換成數(shù)值類型,以便執(zhí)行 range query 范圍查詢操作。

          因為:keyword 類型本質(zhì)是字符串類型的一種,以 keyword 類型做字符串處理比的是首字符的 ASCII 碼值,達不到預(yù)期的效果。

          2.3 方案探討

          接下來是怎么轉(zhuǎn)換字段類型的問題?

          傳統(tǒng)的處理方案如下:

          方案一:重新建模、重新導(dǎo)入數(shù)據(jù)。

          特點:從根源上解決問題。

          方案二:reindex + alias 別名零停機方案。

          特點:重新建模,重新遷移數(shù)據(jù),用別名方式方案讓用戶無感知。

          這時候,我們會思考:有沒有更為簡潔的方式呢?

          本文會提供如下方案三的一種方式, 讓大家評說是否簡潔。

          方案三:convert ingest 預(yù)處理 + reindex 結(jié)合方案。

          特點:無需重新建模,哪個字段不滿足要求就改哪個字段。

          下面我們著重講解一下方案三。

          3、方案三的實戰(zhàn)實現(xiàn)

          3.1 數(shù)據(jù)建模

          我們只有數(shù)據(jù),得從頭模擬,所以建模是第一步。

          PUT test-20220529-04
          {
            "mappings": {
              "properties": {
                "lisCheckItemList": {
                  "type""object",
                  "properties": {
                    "resultChar": {
                      "type""keyword"
                    },
                    "itemName": {
                      "type""keyword"
                    }
                  }
                }
              }
            }
          }

          3.2 數(shù)據(jù)寫入

          POST test-20220529-04/_doc/1
          {
            "lisCheckItemList": [
              {
                "resultChar""1",
                "itemName""項目1"
              },
              {
                "resultChar""2",
                "itemName""項目2"
              },
              {
                "resultChar""11",
                "itemName""項目3"
              },
              {
                "resultChar""22",
                "itemName""項目4"
              },
              {
                "resultChar""25",
                "itemName""項目"
              },
              {
                "resultChar""3",
                "itemName""項目5"
              }
            ]
          }

          POST test-20220529-04/_doc/2
          {
            "lisCheckItemList": [
              {
                "resultChar""1",
                "itemName""項目1"
              },
              {
                "resultChar""2",
                "itemName""項目2"
              }
            ]
          }


          POST test-20220529-04/_doc/3
          {
            "lisCheckItemList": [
              {
                "resultChar""30",
                "itemName""項目1"
              },
              {
                "resultChar""100",
                "itemName""項目2"
              }
            ]
          }

          3.3 數(shù)據(jù)預(yù)處理 convert 實現(xiàn)

          # 物理的mapping 不會變
          PUT _ingest/pipeline/mytx_pipeline_20220530
          {
            "processors": [
              {
                "foreach": {
                  "field""lisCheckItemList",
                  "processor": {
                    "convert": {
                      "field""_ingest._value.resultChar",
                      "type""integer",
                      "ignore_failure"true
                    }
                  }
                }
              }
            ]
          }

          解釋一下,lisCheckItemList 是 object 對象,所以需要foreach 遍歷其下面的值,并通過:ingest.value.resultChar 的方式實現(xiàn)字段類型的 convert 轉(zhuǎn)換。

          做了什么轉(zhuǎn)換呢?由:“keyword”類型變成“integer”類型。

          3.4 數(shù)據(jù) reindex 遷移

          POST _reindex
          {
            "source": {"index""test-20220529-04"},
            "dest": {"index""test-20220529-05""pipeline""mytx_pipeline_20220530"}
          }

          強調(diào)一個語法知識點,也是大家認證考試容易出錯的點。

          這里的 pipeline 要寫到“dest”目標(biāo)索引部分實現(xiàn),而不是“source”源索引部分。

          3.5 數(shù)據(jù)檢索,驗證是否達到預(yù)期

          POST test-20220529-05/_search
          {
            "query": {
              "range": {
                "lisCheckItemList.resultChar": {
                  "gte": 30,
                  "lt": 100
                }
              }
            }
          }


          由于是在數(shù)據(jù)同步的時候,同時切換了數(shù)據(jù)類型。

          所以,本質(zhì)上是沒有問題,rangquery 的檢索自然會達到預(yù)期效果。

          4、小結(jié)

          同步一個小細節(jié),如果我們上面的預(yù)處理 ingest 部分不是做遷移,而是做 update_by_query 會怎么樣?

          這是一個不大不小的“腦洞”。我們結(jié)論說一下, 留給大家去思考和實踐。

          如果僅是:update_by_query 和 ingest 結(jié)合,數(shù)據(jù)的類型也就是 Mapping 依然會是:keyword,但是數(shù)據(jù)的顯示會去掉了“ ”,這實際是“治標(biāo)不治本”的方式,不推薦大家使用。

          小問題蘊含大道理。

          比 reindex 更輕量級的更換字段類型的方式技能,你 Get 到了嗎?

          歡迎大家留言反饋??!

          推薦閱讀

          1. Elasticsearch 預(yù)處理沒有奇技淫巧,請先用好這一招!

          2. Elasticsearch的ETL利器——Ingest節(jié)點

          3. 如何從0到1打磨一門 Elasticsearch 線上直播課?

          短時間快習(xí)得多干貨!

          和全球 1600+ Elastic 愛好者一起精進!


          比同事搶先一步學(xué)習(xí)進階干貨!
          瀏覽 64
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

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

          手機掃一掃分享

          分享
          舉報
          <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>
                  色老板免费精品无码免费视频 | 四虎成人免费毛片在线 | 日本成人三级视频 | 日日干夜夜操 | 人人看人人爱人人搞 |