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

Elasticsearch指標と型の違い


備考

indexがSQLデータベースであるSQLデータベースのテーブルのようなtype sを見るのは簡単です。しかし、これはtype sに近づく良い方法ではありません。

すべてのタイプについて

実際、型は文字通り 、Elasticsearch: _typeによって各ドキュメントに追加された単なるメタデータフィールド_type 。上記の例では、 my_typemy_other_type 2種類が作成されています。つまり、型に関連付けられた各ドキュメントには、 "_type": "my_type"ように自動的に定義された余分なフィールドがあります"_type": "my_type" ;これはドキュメントで索引付けされているため、 検索可能またはフィルタ可能なフィールドになりますが、生のドキュメント自体には影響しません。したがって、アプリケーションで気にする必要はありません。

すべてのタイプは同じインデックスに存在するため、同じインデックスに集約されます。ディスクレベルであっても、同じファイルに存在します。第2のタイプを生成する唯一の分離は論理的なものである。固有であるかどうかにかかわらず、すべてのタイプがマッピングに存在する必要があり、それらのマッピングはすべてクラスタ状態で存在する必要があります。これはメモリを消費し、各タイプが動的に更新されると、マッピングが変化するとパフォーマンスが低下します。

したがって、実際に他のタイプを必要としない限り、単一のタイプのみを定義することがベストプラクティスです。複数のタイプが望ましいシナリオを見るのが一般的です。たとえば、車のインデックスがあるとします。複数のタイプで分割すると便利です。

  • BMW
  • シェビー
  • ホンダ
  • マツダ
  • メルセデス
  • 日産
  • レンジローバー
  • トヨタ
  • ...

この方法で、すべての車を検索するか、オンデマンドでメーカーが制限することができます。これら2つの検索の違いは、次のように簡単です。

GET /cars/_search

そして

GET /cars/bmw/_search

Elasticsearchの新しいユーザーにとって明らかでないことは、2番目のフォームが最初のフォームの特殊化であることです。それは文字どおり書き直されます:

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

値がbmw _typeフィールドで索引付けされていないすべての文書を単純にbmwます。すべてのドキュメントは_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. 名前は任意であなたが望むならそれは型名と一致するかもしれません。

型はインデックス内で控えめに使用する必要があります。通常、インデックスのマッピングを膨らませるためです。あなたは少なくとも1つは持っていなければなりませんが、複数のものを持たなければならないということは何もありません。

よくある質問

  • ほとんど同じ2つ(またはそれ以上)のタイプがあり、タイプごとに固有のフィールドがいくつかある場合はどうなりますか?

インデックス・レベルでは、まばらに使用されているいくつかのフィールドとし、他のタイプは偶数フィールドを使用したことがないという意味(共有されていない少数で非スパースフィールドの束を共有する複数の種類の間で使用されているいずれかのタイプに違いはありません(s))。

言い換えれば、種類に関係なく 、まばらに使用されるフィールドはインデックス全体で疎です。スパース性は、それが別のタイプで定義されているという理由だけでインデックスに利益をもたらしません。

これらの型を組み合わせて、別の型フィールドを追加するだけです。

  • 別々の型は全く同じ方法でフィールドを定義する必要があるのはなぜですか?

各フィールドは本当にLuceneレベルで1回しか定義されていないので、そこにいくつの型があるかには関係ありません。タイプが全く存在しないという事実は、Elasticsearchの特徴であり、論理的な分離に過ぎない

  • 別々に定義された同じフィールドを持つ別々の型を定義できますか?

いいえ、ES 2.x以降で行う方法が見つかった場合は、バグレポートを開く必要があります 。前の質問で指摘したように、Luceneはそれらをすべて1つのフィールドとみなしているため、適切に動作させる方法はありません。

ES 1.xはこれを暗黙の要件として残しました。これにより、インデックス内の1つのシャードのマッピングが同じインデックスの別のシャードと実際に異なる条件を作成することができました。これは事実上競合状態であり、予期しない問題につながる可能性があります。

ルールの例外

  • 親/子ドキュメントで 、同じインデックス内で別の型を使用する必要があります。
    • 親は1つのタイプで暮らしています。
    • 子供は別のタイプで暮らしています(しかし、各子供はその親と同じシャードに住んでいます)。
  • 大量のインデックスを作成することが望ましくなく、スパースフィールドの影響が代替案よりも望ましい非常にニッチな使用例。
    • たとえば、Elasticsearch監視プラグインMarvel(1.xおよび2.x)またはX-Pack Monitoring(5.x +)は、クラスタ、ノード、インデックス、特定のインデックス(インデックスレベル)の変更をElasticsearch自身で監視します。さらには破片。定義されたマッピングの数が効果的に同じですが、作成したインデックスの数:それはユニークなマッピングを持っているか、それがインデックス(ノートを共有することにより、クラスタの負荷を軽減するために、ベストプラクティスに反する可能性があり、それらの文書を隔離するために、毎日5+インデックスを作成することができますnから1に減少する)。
    • これは高度なシナリオですが、タイプ間で共有フィールドの定義を考慮する必要があります。

指標と型の違い 関連する例