乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      干貨 | Elasticsearch 數(shù)據(jù)建模指南

       銘毅天下 2022-04-25
      0、題記

      我在做 Elasticsearch 相關(guān)咨詢和培訓(xùn)過程中,發(fā)現(xiàn)大家普遍更關(guān)注實戰(zhàn)中涉及的問題,下面我選取幾個常見且典型的問題,和大家一起分析一下。

      • 訂單表、賬單表父子文檔可以實現(xiàn)類似 SQL 的左連接嗎?通過 canal 同步到 ES 中,能否實現(xiàn)類似左連接的效果?具體應(yīng)該如何建模?
      • 一個人管理 1000  家連鎖門店,如何更高效地查詢自己管轄的商品類目?企微 一個人維護了 1000 個員工,如何快速查詢自己管轄的員工信息?
      • 隨著業(yè)務(wù)的增長,一個索引的字段數(shù)據(jù)不斷膨脹(商品場景變化,業(yè)務(wù)一直加字段),有什么解決方法?
      • 一個索引字段個數(shù)設(shè)置為 1500 個,超出這個限制,會不會消耗 CPU 資源和造成寫入堆積?
      • 日志診斷用于機器學(xué)習(xí)基線,需要將 message 分離出來,怎么在寫入前搞定?

      如果我們對上述實戰(zhàn)問題進行歸類,就都可以歸結(jié)為 Elasticsearch 數(shù)據(jù)建模問題。

      本文將以實戰(zhàn)問題為基準,手把手帶你實踐 Elasticsearch 數(shù)據(jù)建模全流程,重點解析基于業(yè)務(wù)角度、數(shù)據(jù)量角度、Setting 、Mapping ,以及復(fù)雜索引關(guān)聯(lián),這五個層面中涉及的數(shù)據(jù)建模實戰(zhàn)問題,讓你學(xué)完即可應(yīng)用到工作中。

      1、為什么要做數(shù)據(jù)建模?

      我們選型傳統(tǒng)的數(shù)據(jù)庫,這里以 MySQL 為例,做數(shù)據(jù)存儲前需要考慮的問題如下:

      • 數(shù)據(jù)庫要不要做讀寫分離?
      • 分幾張表存儲?
      • 每個表的名是什么?
      • 每個表是按照業(yè)務(wù)劃分嗎?
      • 單表數(shù)據(jù)大了怎么搞?分庫分表還是其他?
      • 每個表要有哪些字段?每個字段設(shè)置什么類型?如何設(shè)計合理的字段類型,才能保證節(jié)省存儲?
      • 哪些字段需要建索引?
      • 哪些字段需要設(shè)置外鍵?
      • 表之間要不要建立關(guān)聯(lián)?如何實現(xiàn)關(guān)聯(lián)聯(lián)動查詢?
      • 關(guān)聯(lián)查詢可能會很慢?如何設(shè)計階段優(yōu)化建模才能提高響應(yīng)速度?

      以上這些疑問也均是數(shù)據(jù)建模問題。在 MySQL 中我們往往認為建模非常有必要,但反觀 Elasticsearch ,“上手快”這類先入為主的觀念已根植在很多同學(xué)心中,使得大家忽略了 Elasticsearch 數(shù)據(jù)建模的重要性。

      接下來,我們基于 MySQL 做數(shù)據(jù)存儲需要考慮的問題,重新審視數(shù)據(jù)建模的定義,內(nèi)容如下。

      • 數(shù)據(jù)模型是對描述數(shù)據(jù)、數(shù)據(jù)聯(lián)系、數(shù)據(jù)語義和一致性約束進行標準化的抽象模型。
      • 數(shù)據(jù)建模是為存儲在數(shù)據(jù)庫中的資源創(chuàng)建和分析數(shù)據(jù)模型的過程。
      • 數(shù)據(jù)建模主要目的是表示系統(tǒng)內(nèi)的數(shù)據(jù)類型、對象之間的關(guān)系及其屬性。
      • 數(shù)據(jù)模型有助于了解需要哪些數(shù)據(jù)以及應(yīng)如何組織數(shù)據(jù)。

      到這里,相信你已經(jīng)初步明晰了數(shù)據(jù)建模的重要性。但我還想提醒你的是,“一把梭用法,上來就是干”并不是捷徑,尤其到了項目中后期,極易暴露出問題。經(jīng)歷的項目越多,你會發(fā)現(xiàn)建模的時間不能省。

      下面我們具體分析一下為什么要數(shù)據(jù)建模?

      相比于 MySQL,Elasticsearch 有非??旖莸?/span>優(yōu)勢

      Elasticsearch 支持動態(tài)類型檢查和匹配。也就是說,當我們寫入索引數(shù)據(jù)的時候,可以不提前指定數(shù)據(jù)類型,直接插入數(shù)據(jù)。

      以類似天眼查、企查查的工商實戰(zhàn)數(shù)據(jù)為例(已做脫敏處理),如果利用以下語句直接創(chuàng)建索引和寫入一條數(shù)據(jù),豈不是很快?

      PUT company_index/_doc/1
      {
        "regist_id": 1XX1600000000012,
        "company_name""北京XX長江創(chuàng)業(yè)投資有限公司",
        "regist_id_new""191XX160066933968XC",
        "legal_representative""徐X武",
        "scope_bussiness""創(chuàng)業(yè)投資業(yè)務(wù);代理其他創(chuàng)業(yè)投資企業(yè)等機構(gòu)或個人的創(chuàng)業(yè)投資業(yè)務(wù);創(chuàng)業(yè)投資咨詢業(yè)務(wù);為創(chuàng)業(yè)企業(yè)提供管理服務(wù)業(yè)務(wù);參與設(shè)立創(chuàng)業(yè)投資企業(yè)與企業(yè)投資管理顧問機(依法須經(jīng)批準的項目,經(jīng)相關(guān)部門批準后方可開展經(jīng)營活)",
        "registration_status""在營(開業(yè))企業(yè)",
        "approval_date""201X年04月13日",
        "registration_number""191XX160066933968XC",
        "establishment_time""200X年12月03日",
        "address""北京市黃河XX路西首育青小區(qū)",
        "register_capital": 3000,
        "business_starttime""20XX年12月03日",
        "registration_authority""北XX工商行政管理局",
        "company_type""其他有限責(zé)任公司",
        "enttype": 1190,
        "enttypename""法定代表人:",
        "pripid""1XXX102201305305801X",
        "uniscid""1XXX160066933968XC"
      }

      相比于 MySQL 中一個字段一個字段地敲定,這樣操作確實節(jié)省了很多時間。但隨著后續(xù)數(shù)據(jù)量激增,副作用便會很快顯現(xiàn)出來。該處理方式的弊端:

      • 首先是極大地浪費了存儲空間,所有字符串類型數(shù)據(jù)都存儲為 text + keyword 組合類型,這種很多業(yè)務(wù)字段都是非必須的;

      • 其次字符串類型默認分詞 standard,無法滿足中文精細化分詞檢索的需求。

      接下來,結(jié)合我自己工作中早期系統(tǒng)的一個案例,我們做進一步分析。

      5 個數(shù)據(jù)節(jié)點集群(5 個分片,1 個副本),微博數(shù)據(jù)每日增量 5000W+(增量存儲 150GB),核心數(shù)據(jù)磁盤 10TB 左右,很明顯該系統(tǒng)面臨存儲上限問題。

      我們當時就上述業(yè)務(wù)數(shù)據(jù)規(guī)劃了一個大索引,比如微博數(shù)據(jù)一個索引,微信數(shù)據(jù)一個索引。但微博索引最多只能存儲 20 天左右的數(shù)據(jù),然后就得走刪除索引數(shù)據(jù)的操作。由于 1 個索引只能通過 delete_by_query 刪除部分數(shù)據(jù),而 delete_by_query 的特點是版本號更新的邏輯刪除,實際效果是越刪數(shù)據(jù)量越大,磁盤占用率激增。加上是線上環(huán)境,壓力之大,處理難度之大,經(jīng)歷過你就知道有多苦。

      這也是很多大廠在面試候選人的時候,尤其偏愛數(shù)據(jù)建模能力強的工程師的主要原因之一。

      比如下圖是美團對大數(shù)據(jù)開發(fā)高級工程師的崗位要求,第一條就是“深入理解業(yè)務(wù),對業(yè)務(wù)服務(wù)流程進行合理的抽象和建模。”

      從以上兩個反例,以及這條招聘信息中便可以窺探出數(shù)據(jù)建模的重要性。下面我們具體說說如何做數(shù)據(jù)建模。

      2、Elasticsearch 如何數(shù)據(jù)建模?

      在做數(shù)據(jù)建模之前,會先進行架構(gòu)設(shè)計,架構(gòu)環(huán)節(jié)涉及選型、集群規(guī)劃、節(jié)點角色劃分。

      本文涉及的建模傾向于索引層面、數(shù)據(jù)層面的建模。為了讓你學(xué)完即可應(yīng)用到工作中,我會結(jié)合項目實戰(zhàn)進行講解。

      2.1 基于業(yè)務(wù)角度建模

      Elasticsearch 適用范圍非常廣,包括電商、快遞、日志等各行各業(yè)。涉及索引層面的設(shè)計,和業(yè)務(wù)貼合緊密。

      其一:業(yè)務(wù)一定要細分。

      分成哪幾類數(shù)據(jù),每類數(shù)據(jù)歸結(jié)為一個索引還是多個索引,這是產(chǎn)品經(jīng)理、架構(gòu)師、項目經(jīng)理要討論敲定的問題。比如大數(shù)據(jù)類的數(shù)據(jù),可以按照業(yè)務(wù)數(shù)據(jù)分為微博索引、微信索引、Twiiter 索引、Facebook 索引等。

      其二:多個業(yè)務(wù)類型需不需要跨索引檢索?

      跨索引檢索的痛點是字段不統(tǒng)一、不一致,需要寫非常復(fù)雜的 bool 組合查詢語句來實現(xiàn)。為了避免這種情況,最好的方式就是提前建模。每一類業(yè)務(wù)數(shù)據(jù)的相同或者相似字段,采取統(tǒng)一建模的方式。

      下面我們舉一個實際的例子加以分析。微博、微信、Twitter、Facebook 都有的字段,可以設(shè)計如下:

      字段名稱字段中文含義字段類型
      publish_time發(fā)布時間date
      author作者keyword
      cont正文內(nèi)容text

      這樣設(shè)計的好處是:字段統(tǒng)一,寫查詢 DSL 無需特殊處理,非常快捷方便。所以,在設(shè)計階段,多個業(yè)務(wù)索引數(shù)據(jù)要盡可能地“求同存異”。具體來說:

      • 求同指的是相同或者相近含義字段,一定要統(tǒng)一字段名、統(tǒng)一字段類型;

      • 存異指的則是特定業(yè)務(wù)數(shù)據(jù)特有字段類型,可以獨立設(shè)計字段名稱和類型。

      比如微博信息來源字段有手機 App 或者網(wǎng)頁等,別的業(yè)務(wù)索引如果沒有,獨立建模就可以。

      類似這些建模信息可以統(tǒng)一 Excel 存儲,統(tǒng)一 git 多人協(xié)作管理。

      多索引管理一般優(yōu)先推薦使用模板(template)和 別名(alias)結(jié)合的方式。

      • 模板的特點:相同前綴名稱的索引可以歸結(jié)為一大類,一次創(chuàng)建,N 多索引共享,非常方便。

      • 別名的特點:多個索引可以映射到一個別名,方便多索引以相同的名稱統(tǒng)一對外提供服務(wù)。

      2.2 基于數(shù)據(jù)量角度建模

      如本文前面所述,我是吃過單索引激增的虧,所以對于時序性數(shù)據(jù)(日志數(shù)據(jù)、大數(shù)據(jù)類數(shù)據(jù))等,我強烈建議你基于時間切分索引,具體如下圖所示。

      當然,其他可用的方案非常多,這里我列舉如下,供你選型參考。

      由此可見,時序管理數(shù)據(jù)的優(yōu)點非常明顯。

      • 其一是靈活?;跁r間切分索引非常方便,刪除數(shù)據(jù)屬于物理刪除。
      • 其二則是快速。特定業(yè)務(wù)數(shù)據(jù)配合冷熱集群架構(gòu),確保高配機器對應(yīng)熱數(shù)據(jù),提升檢索效率和用戶體驗。

      2.3 基于 Setting 層面建模

      Setting 層面又分為靜態(tài) Setting 和動態(tài) Setting 兩種。

      一種是靜態(tài) Settings,一旦設(shè)置后,后續(xù)不可修改。如 number_of_shards

      另一種是動態(tài) Setting,索引創(chuàng)建后,后面隨時可以更新。如 number_of_replicas, max_result_window, refresh_interval 。

      僅就建模階段最核心的問題,拆解如下。

      • 問題一:索引設(shè)置多少個分片?多少個副本?

      這里有個認知前提,就是主分片數(shù)一旦設(shè)置后就不可以修改,副本分片數(shù)可以靈活動態(tài)調(diào)整。

      主分片設(shè)計一般會考量總體數(shù)據(jù)量、集群節(jié)點規(guī)模,這點在集群規(guī)劃層面會著重強調(diào)。一般主分片數(shù)要考慮集群未來動態(tài)擴展,通常設(shè)置為數(shù)據(jù)節(jié)點的 1 倍或者 1~3 倍之間的值。

      副本分片是保證集群的高可用性,普通業(yè)務(wù)場景建議至少設(shè)置一個副本。

      • 問題二:refresh_interval 一般設(shè)置多大?

      默認值 1s,這意味著在寫入階段,每秒都會生成一個分段。

      refresh_interval 的目的是:數(shù)據(jù)由 index buffer 的堆內(nèi)存緩存區(qū)刷新到堆外內(nèi)存區(qū)域,形成 segment,以使得搜索可見。

      在實際業(yè)務(wù)場景里,如果寫入的數(shù)據(jù)不需要近實時搜索可見,可以適當?shù)卦谀0?、索引層面調(diào)大這個值,當然也可以動態(tài)調(diào)整,比如調(diào)整為 30s 或者  60s。

      • 問題三:max_result_window 要不要修改默認值?

      這里同樣有個認知前提,就是對于深度翻頁的 from + size 實現(xiàn),越往后翻頁越慢。其實你對比看主流搜索引擎,比如 Google、百度、360、Bing 均不支持一下跳轉(zhuǎn)到最后一頁,這就是最大翻頁上限限制。

      其實在基本業(yè)務(wù)層面也很好理解,按照相關(guān)度返回結(jié)果,前面幾頁是最相關(guān)的,越往后相關(guān)度越低。比如默認值 10000,也就是說如果每頁顯示 10 條數(shù)據(jù),可以翻 1000 頁。基本業(yè)務(wù)場景已經(jīng)足夠了。因此不建議調(diào)大該值。

      如果需要向后翻頁查詢,推薦 search_after 查詢方式。如果需要全量遍歷或者全量導(dǎo)出數(shù)據(jù),推薦 scroll 查詢方式。

      • 問題四:管道預(yù)處理怎么用?

      管道預(yù)處理的好處很多,雖然 5.X 版本就有了這個功能,但實戰(zhàn)環(huán)境用起來還不多。

      管道 ingest pipeline 就相當于大數(shù)據(jù)的 ETL 抽取、轉(zhuǎn)換、加載的環(huán)節(jié),或者類似 logstash filter 處理環(huán)節(jié)。一些數(shù)據(jù)打標簽、字段類型切分、加默認字段、加默認值等的預(yù)處理操作都可以借助 ingest pipelie 實現(xiàn)。

      這里給出索引層面 Setting  設(shè)置的簡單模板,供你進一步學(xué)習(xí)參考,如下定義了 indexed_at 缺省的管道,同時在索引 my_index_0001 指定了該缺省管道,這樣做的好處,是每個新增的數(shù)據(jù)都會加了插入時刻的時間戳:indexed_at 字段,無需我們在業(yè)務(wù)層面手動處理,非常靈活和方便。

      更多設(shè)置,推薦閱讀官方文檔,地址如下:

      https://www./guide/en/elasticsearch/reference/current/index-modules.html#index-modules-settings

      PUT _ingest/pipeline/indexed_at
      {
        "description""Adds indexed_at timestamp to documents",
        "processors": [
          {
            "set": {
              "field""_source.indexed_at",
              "value""{{_ingest.timestamp}}"
            }
          }
        ]
      }



      PUT my_index_0001
      {
        "settings": {
          "number_of_replicas": 1,
          "number_of_shards": 3,
          "refresh_interval""30s",
          "index": {
            "default_pipeline""indexed_at"
          }
        }, 
        "mappings": {
          "properties": {
            "cont": {
              "type""text",
              "analyzer""ik_max_word",
              "fields": {
                "keyword": {
                  "type""keyword"
                }
              }
            }
          }
        }
      }

      2.4 基于 Mapping 層面建模

      Mapping 層面核心是字段名稱、字段類型、分詞器選型、多字段 multi_fields 選型,以及字段細節(jié)(是否索引、是否存儲等)的敲定。

      (1)字段命名要規(guī)范

      索引名稱不允許用大寫,字段名稱官方?jīng)]有限制,但是可以參考 Java 編碼規(guī)范。我還真見過學(xué)員用中文或者拼音命名的,非常不專業(yè),大家一定要避免。

      (2)字段類型要合理

      要結(jié)合業(yè)務(wù)類型選擇合適的字段類型。比如 integer 能搞定的,就不要用 long、float 或 double。

      注意,字符串類型在 5.X 版本之后分為兩種類型:

      • 一種是 keyword,適合精準匹配、排序和聚合操作;

      • 另一種是 text,適合全文檢索。默認值 text & keyword 組合不見得是最優(yōu)的,選型時候要結(jié)合業(yè)務(wù)選擇。比如優(yōu)先選擇 keyword 類型,keyword 走倒排索引更快。

      再舉個例子,實戰(zhàn)中情感值介于 0~100 之間,50 代表中性,0~50 代表負面,50~100 代表正面。如果使用 integer 查詢的時候要 range query,而實際存儲可以增加字段:0~50 設(shè)置為 -1,50 設(shè)置為 0,50~100 設(shè)置為 1,三種都是 keyword 類型,檢索時直接走 term 檢索會非???。

      (3)分詞器要靈活

      實戰(zhàn)中中文分詞器用得比較多,中文分詞又分為 ansj,結(jié)巴,IK 等。以 IK 舉例,可以細分為 ik_smart 粗粒度分詞、ik_max_word 細粒度分詞。

      在工作中,要結(jié)合業(yè)務(wù)選擇合適的分詞器,分詞器一旦設(shè)定是不可以修改的,除非 reindex。

      分詞器選型后,都會有動態(tài)詞典的更新問題。更新的前提是不要僅使用開源插件原生詞典,而是要在平時業(yè)務(wù)中自己多積累特定業(yè)務(wù)數(shù)據(jù)詞典、詞庫。

      如果要動態(tài)更新:一般推薦第三方更新插件借助數(shù)據(jù)庫更新實現(xiàn)。如果普通分詞都不能滿足業(yè)務(wù)需要,可以考慮 ngram 自定義分詞方式實現(xiàn)更細粒度分詞。

      (4)multi_fields 適機使用

      同一個字段根據(jù)需要可以設(shè)置多種類型。實戰(zhàn)業(yè)務(wù)中,對用特定中文詞明明存在,卻無法召回的情況,采用字詞混合索引的方式得以滿足。

      所謂字詞混合,實際就是 standard 分詞器實現(xiàn)單字拆解,以及 ik_max_word 實現(xiàn)中文切詞結(jié)合的方式。檢索的時候 bool 對兩種分詞器結(jié)合,就可以實現(xiàn)相對精準的召回效果。

      PUT mix_index
      {
        "mappings": {
            "properties": {
              "content": {
                "type""text",
                "analyzer""ik_max_word",
                "fields": {
                  "standard": {
                    "type""text",
                    "analyzer""standard"
                  },
                  "keyword": {
                    "type""keyword",
                    "ignore_above": 256
                  }
                }
              }
            }
          }
      }

      POST mix_index/_search
      {
        "query": {
          "bool": {
            "should": [
              {
                "match_phrase": {
                  "content""佟大"
                }
              },
              {
                "match_phrase": {
                  "content.standard""佟大"
                }
              }
            ]
          }
        }
      }

      為了方便你記憶和使用,這里我把字段細節(jié)總結(jié)在如下這張表格中。




      核心參數(shù)默認值釋義
      enabledtrue僅適用于 Mapping 頂層以及 Object 對象,設(shè)置為 false 后該字段將不再被解析。
      indextrue控制是否對字段值進行索引,設(shè)置為 false 的字段不能被查詢。
      doc_valuestrue正排索引,除了 text 類型外的其他類型默認開啟,用于聚合和排序分析。
      fielddatafalse是否為 text 類型啟動 fielddata,實現(xiàn) text 字段排序和聚合分析。
      storefalse是否存儲該字段值。
      coercetrue是否開啟自動數(shù)據(jù)類型轉(zhuǎn)換功能,比如 字符串轉(zhuǎn)數(shù)字、浮點轉(zhuǎn)整型。true 代表可以轉(zhuǎn)換,false 代表不可以轉(zhuǎn)換。
      fields根據(jù)業(yè)務(wù)需要而定靈活使用多字段解決多樣的業(yè)務(wù)需求。
      dynamictrue控制 mapping 的動態(tài)自動更新。
      date_detectiontrue是否自動識別類型。

      我們再來分析一下數(shù)據(jù)建模的流程,如下圖所示。

      數(shù)據(jù)建模的流程圖

      首先,根據(jù)業(yè)務(wù)選擇合適的數(shù)據(jù)類型。

      注意字符串類型分為兩種 text 和 keyword類型;盡量選擇貼近實際大小的數(shù)據(jù)類型;nested 和 join 復(fù)雜類型需根據(jù)業(yè)務(wù)特點選型,具體會在下一部分詳細闡述。

      其次,判定是否需要檢索,如果不需要,index 設(shè)置為 false 即可。

      然后,判定是否需要排序和聚合操作,如果不需要可以設(shè)置 doc_values 為 false。

      最后,考慮一下是否需要另行存儲,會結(jié)合使用 store 和  _source 字段。

      Mapping 層面要強調(diào)的是:盡量不要使用默認的 dynamic 動態(tài)字段類型,強烈建議 strict 嚴格控制字段,避免字段“暴漲”導(dǎo)致不可預(yù)知的風(fēng)險,比如字段數(shù)超過默認 1000 個的上限、磁盤大于預(yù)期的激增等。

      2.5 基于復(fù)雜索引關(guān)聯(lián)建模

      要摒棄 MySQL 的多表關(guān)聯(lián)建模思想,因為 MySQL 中的范式思想都不再適用于 Elasticsearch?;仡櫸恼麻_頭的幾個多表關(guān)聯(lián)問題,Elasticsearch 能提供的核心解決方案如下。

      (1) 寬表方案

      這是空間換時間的方案,就是允許部分字段冗余存儲的存儲方式。實戰(zhàn)舉例如下。

      用戶索引:user。

      博客索引:blogpost。

      一個用戶可以發(fā)表多篇博客。按照傳統(tǒng)的 MySQL 建表思想:兩個表建立個用戶外鍵,即可搞定一切。而對于 Elasticsearch,我們更愿意在每篇博文后面都加上用戶信息(這就是寬表存儲的方案),看似存儲量大了,但是一次檢索就能搞定搜索結(jié)果。

      PUT user/_doc/1
      {
        "name":     "John Smith",
        "email":    "john@smith.com",
        "dob":      "1970/10/24"
      }

      PUT blogpost/_doc/2
      {
        "title":    "Relationships",
        "body":     "It's complicated...",
        "user":     {
          "id":       1,
          "name":     "John Smith" 
        }
      }


      GET /blogpost/_search
      {
        "query": {
          "bool": {
            "must": [
              {
                "match": {
                  "title""relationships"
                }
              },
              {
                "match": {
                  "user.name""John"
                }
              }
            ]
          }
        }
      }

      (2) nested 方案

      • 適用場景:1 對少量,子文檔偶爾更新、查詢頻繁的場景。

      如果需要索引對象數(shù)組并保持數(shù)組中每個對象的獨立性,則應(yīng)使用嵌套 Nested 數(shù)據(jù)類型而不是對象 Oject 數(shù)據(jù)類型。

      nested 文檔的優(yōu)點是可以將父子關(guān)系的兩部分數(shù)據(jù)(如博客+評論)關(guān)聯(lián)起來,我們可以基于nested 類型做任何的查詢。但缺點是查詢速度相對較慢,更新子文檔需要更新整篇文檔。

      (3) join 父子文檔方案

      • 適用場景:子文檔數(shù)據(jù)量要明顯多于父文檔的數(shù)據(jù)量,存在 1 對多量的關(guān)系;子文檔更新頻繁的場景。

      比如 1 個產(chǎn)品和供應(yīng)商之間就是 1 對 N 的關(guān)聯(lián)關(guān)系。當使用父子文檔時,使用 has_child 或者 has_parent 做父子關(guān)聯(lián)查詢。優(yōu)點是父子文檔可獨立更新,但維護 Join 關(guān)系需要占據(jù)部分內(nèi)存,查詢較 Nested 更耗資源。

      注意:5.X 之前版本叫父子文檔(多 type 實現(xiàn)),6.X 之后高版本是 join 類型(單 type 類型)。

      (4) 業(yè)務(wù)層面實現(xiàn)關(guān)聯(lián)

      需通過多次檢索獲取所需的關(guān)鍵字段,業(yè)務(wù)層面自己寫代碼實現(xiàn)。

      這里小結(jié)一下,以上四種方式便是 Elasticsearch 能實現(xiàn)的全量多表關(guān)聯(lián)方案。實戰(zhàn)建模階段,一定要結(jié)合自己的業(yè)務(wù)場景,盡量往上靠,先通過 kibana dev tool 模擬實現(xiàn),找到契合自己業(yè)務(wù)的多表關(guān)聯(lián)方案。

      此外我還要強調(diào)的是:多表關(guān)聯(lián)都會有性能問題,數(shù)據(jù)量極大且檢索性能要求高的場景需要慎用。這里我摘取了官方文檔對應(yīng)的描述如下,供你參考。

      尤其應(yīng)該避免多表關(guān)聯(lián)。Nested 嵌套可以使查詢慢幾倍,而 Join 父子關(guān)系可以使查詢慢數(shù)百倍。

      3、總結(jié)

      最后,我們再來總結(jié)一下建模其他核心考量因素。

      • 盡量空間換時間:能多個字段解決的不要用腳本實現(xiàn)。

      • 盡量前期數(shù)據(jù)預(yù)處理,不要后期腳本。優(yōu)先選擇 ingest process 數(shù)據(jù)預(yù)處理實現(xiàn),盡量不要留到后面 script 腳本實現(xiàn)。

      • 能指定路由的提前指定路由。寫入的時候指定路由,檢索的時候也同樣適用路由。

      • 能前置的盡量前置,讓后面檢索聚合更加清爽。比如 index sorting 前置索引字段排序是非常好的方式。

      數(shù)據(jù)建模是 Elasticsearch 開發(fā)實戰(zhàn)中非常重要的一環(huán),也是項目管理角度中的設(shè)計環(huán)節(jié)的重中之重,你一定要重視!千萬不要著急寫業(yè)務(wù)代碼,以“代碼之前,設(shè)計先行”作為行動準繩。

      感謝你的時間!有 Elasticsearch 建模問題歡迎留言交流。

      本文成文于:2021年8月11日

      推薦


      1、重磅 | 死磕 Elasticsearch 方法論認知清單(2021年國慶更新版)
      2、如何從0到1打磨一門 Elasticsearch 線上直播課?(口碑不錯)
      3、如何系統(tǒng)的學(xué)習(xí) Elasticsearch ?
      4、Elasticsearch是一把梭,用起來再說?!
      5、干貨 | 論Elasticsearch數(shù)據(jù)建模的重要性

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

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

      比同事搶先一步學(xué)習(xí)進階干貨!

        轉(zhuǎn)藏 分享 獻花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多