Looking for elasticsearch Answers? Try Ask4KnowledgeBase
Looking for elasticsearch Keywords? Try Ask4Keywords

Elasticsearch指數和類型之間的差異


備註

很容易看到type類似於SQL數據庫中的表,其中index是SQL數據庫。但是,這不是一種接近type的好方法。

關於類型

實際上,類型實際上只是Elasticsearch: _type添加到每個文檔的元數據字段。上面的示例創建了兩種類型: my_typemy_other_type 。這意味著與類型相關聯的每個文檔都有一個額外的字段,自動定義為"_type": "my_type" ;這是使用文檔編制索引,從而使其成為可搜索或可過濾的字段 ,但它不會影響原始文檔本身,因此您的應用程序無需擔心它。

所有類型都存在於同一索引中,因此位於索引的相同集合分片中。即使在磁盤級別,它們也存在於相同的文件中。創建第二種類型提供的唯一分離是合乎邏輯的。每種類型,無論它是否唯一,都需要存在於映射中,並且所有這些映射必須存在於集群狀態中。這會佔用內存,如果每種類型都是動態更新的,它會隨著映射的變化而降低性能。

因此,最佳實踐是僅定義單個類型,除非您確實需要其他類型。通常會看到需要多種類型的場景。例如,假設您有汽車索引。您可以使用多種類型對其進行細分:

  • 寶馬
  • 煩擾
  • 本田
  • 馬自達
  • 奔馳
  • 日產
  • rangerover
  • 豐田
  • ...

這樣,您可以搜索所有汽車或按製造商按需限制。這兩次搜索之間的區別很簡單:

GET /cars/_search

GET /cars/bmw/_search

對Elasticsearch的新用戶來說,不明顯的是第二種形式是第一種形式的特化。它實際上被重寫為:

GET /cars/_search
{
  "query": {
    "bool": {
      "filter": [
        {
          "term" : {
            "_type": "bmw"
          }
        }
      ]
    }
  }
}

它只是過濾掉任何未使用值為bmw_type字段編制索引的文檔。由於每個文檔都以其類型索引為_type字段,因此這是一個非常簡單的過濾器。如果在任一示例中都提供了實際搜索,則過濾器將根據需要添加到完整搜索中。

因此,如果類型相同,則提供單一類型(例如,本示例中的manufacturer )並且有效地忽略它會好得多。然後,在每個文檔中,顯式提供一個名為make的字段或您喜歡的任何名稱 ,並在您想要限制它時手動過濾它。這會將映射的大小減小到1/n ,其中n是單獨類型的數量。它確實為每個文檔添加了另一個字段,這是為了簡化映射。

在Elasticsearch 1.x和2.x中,這樣的字段應該定義為

PUT /cars
{
  "manufacturer": { <1>
    "properties": {
      "make": { <2>
        "type": "string",
        "index": "not_analyzed"
      }
    }
  }
}
  1. 這個名字是任意的。
  2. 該名稱是任意的如果您也想要它它可以匹配類型名稱。

在Elasticsearch 5.x中,上面的代碼仍然可以使用(它已被棄用),但更好的方法是使用:

PUT /cars
{
  "manufacturer": { <1>
    "properties": {
      "make": { <2>
        "type": "keyword"
      }
    }
  }
}
  1. 這個名字是任意的。
  2. 該名稱是任意的如果您也想要它它可以匹配類型名稱。

應該在索引中謹慎使用類型,因為它會使索引映射膨脹,通常沒有太大的好處。你必須至少有一個,但沒有任何東西說你必須有一個以上。

常見問題

  • 如果我有兩個(或更多)類型大多相同但每個類型有一些唯一字段會怎麼樣?

在索引級別,存在正在與被稀疏地使用幾個字段多種類型的,與幾個不共享(意味著其它類型甚至從未共享一束非稀疏字段之間使用的一個類型之間沒有差別採用現場(一個或多個))。

換句話說: 無論類型如何,稀疏使用的字段在索引上都是稀疏的。稀疏性不會因為它是以單獨的類型定義而對索引有益 - 或者真正受到傷害。

您應該只組合這些類型並添加單獨的類型字段。

  • 為什麼單獨的類型需要以完全相同的方式定義字段?

因為每個字段實際上只在Lucene級別定義一次,無論有多少類型。類型存在的事實是Elasticsearch的一個特徵,它只是一個邏輯分離。

  • 我可以定義具有不同定義的相同字段的單獨類型嗎?

不。如果您設法在ES 2.x或更高版本中找到這樣做的方法,那麼您應該打開一個錯誤報告 。如前一個問題所述,Lucene將它們視為單個字段,因此無法使其正常工作。

ES 1.x將此作為隱式要求,允許用戶創建條件,其中索引中的一個分片映射實際上與同一索引中的另一個分片不同。這實際上是一種競爭條件, 可能會導致意外問題。

規則的例外情況

  • 父/子文檔需要在同一索引中使用單獨的類型。
    • 父母住在一種類型。
    • 孩子生活在一個單獨的類型中(但每個孩子與其父母住在同一個碎片中)。
  • 非常小眾的使用案例,其中創建大量的指數是不可取的,稀疏領域的影響優於替代方案。
    • 例如,Elasticsearch監控插件Marvel(1.x和2.x)或X-Pack監控(5.x +)監控Elasticsearch本身的集群,節點,索引,特定索引(索引級別)的變化,甚至是碎片。它可以每天創建5個以上的索引來隔離那些具有唯一映射的文檔, 或者它可能違反最佳實踐以通過共享索引來減少集群負載(注意:已定義映射的數量實際上是相同的,但是創建的索引的數量從n減少到1)。
    • 這是一種高級方案,但您必須考慮跨類型的共享字段定義!

指數和類型之間的差異 相關例子