Elasticsearch 仕上げメモ (5)

es6 より上のバージョンに関する注意:

1. Elasticsearch-head は、6.x より上のバージョンに接続すると 406 エラーを報告します。

Content-Type header [application/x-www-form-urlencoded] is not supported

理由:

ES の 6.x バージョンでは、Content-Type の問題が厳密に制御されています。application/x-www-form-urlencoded は JSON 形式のコンテンツ本文をサポートしていないため、変更する必要があります

解決:

head プラグインのインストール ディレクトリ -> elasticsearch-head フォルダー ->vendor.js ファイルを入力します。

2 か所を変更します。

1. 6886行 contentType: "application/x-www-form-urlencoded"
    改成 contentType: "application/json;charset=UTF-8" 
2. 7574行 var inspectData = s.contentType === "application/x-www-form-urlencoded" && 
    改成 var inspectData = s.contentType === "application/json;charset=UTF-8" &&

 

2.タイプ

Elasticsearch の最初のリリース以来、各ドキュメントは個別のインデックスに保存され、タイプが与えられます。これは、インデックス付けされるドキュメントまたはエンティティのタイプを表すマッピング タイプです。たとえば、twitter インデックスには、ユーザー タイプとツイート タイプがある場合があります。 。

各マッピング タイプには独自のフィールドがあるため、ユーザー タイプには full_name フィールド、user_name フィールド、および email フィールドが含まれる場合がありますが、ツイート タイプには、ユーザー タイプと同様に content フィールド、tweet_at フィールド、および user_name フィールドがある場合があります。

各ドキュメント タイプにはタイプ名を格納する _type メタ フィールドがあり、クエリ (検索) は URL で指定されたタイプ名に従って 1 つ以上のタイプ (type) に限定されます。

GET twitter/user,tweet/_search
{
  "query": {
    "match": {
      "user_name": "kimchy"
    }
  }
}

_type フィールドは、ドキュメントの _id フィールドと結合して _uid フィールドを生成するために使用されるため、同じ _id を持つ異なるタイプのドキュメントが同じインデックス内に存在できます。タイプはドキュメント間の親子関係を確立するためにも使用されるため、質問タイプのドキュメントがアンサー タイプのドキュメントの親ドキュメントになる場合があります。

最初に、リレーショナル データベースの「インデックス」と「ライブラリ」は類似しており、「タイプ」と「テーブル」は同等であると述べました。
これは誤った対比であり、誤った仮定につながります。リレーショナルデータベースでは、「テーブル」は互いに独立しており、ある「テーブル」の列は、別の「テーブル」の同じ名前の列とは関係がなく、互いに影響を与えません。ただし、これは型のフィールドには当てはまりません。

Elasticsearch インデックスでは、同じ名前を持つすべての異なるタイプのフィールドが内部的に同じ lucene フィールド ストレージを使用します。つまり、上記の例では、ユーザー タイプの user_name フィールドとツイート タイプの user_name フィールドが 1 つのフィールドに格納されており、2 つのタイプの user_name は同じフィールド定義を持つ必要があります。

これにより、たとえば、同じインデックス内の「削除された」フィールドに日付値をある型で保存し、ブール値を別の型で保存する場合に問題が発生する可能性があります。

最後に、同じインデックス内に同じフィールドが少数しかないドキュメント、またはすべてのフィールドが異なるドキュメントを保存すると、データがまばらになり、Lucene の効果的なデータ圧縮機能に影響します。

そのため、6.X では、インデックスには 1 つの型のみを持つことが強制されますが、7.X では型の概念が直接削除されます。

しかし、問題があります。ES5.X バージョンでは、データベースの結合機能と同様に、親子ドキュメントを使用して複数テーブルの関連付けが実現されます。実装の核心は、1 つのインデックスで複数の型をサポートすることです (インデックス) ES5.X の助けを借りて。ES6.X バージョンでは、各インデックスで 1 つのタイプのみがサポートされます。mysqlと同様に複数のテーブルの関連付けを実現するにはどうすればよいですか? ——Elasticsearch 6.X の新しいタイプの結合

詳細については、公式ドキュメントを参照してください: https://www.elastic.co/guide/en/elasticsearch/reference/current/parent-join.html

3. 特殊文字とキーワードのクエリ

es5 バージョンでは、単語分割を行わずに用語やワイルドカードなどを直接使用してフィールドをクエリできますが、es6 以降ではクエリが無効になることがわかります。「+」などの特殊文字は検索条件に含めることができず、エスケープされます。も無効です。

{
	"query": {
		"bool": {
			"filter": [{
				"term": {
					"user_id":"user-x"
				}
			}]
		}
	}
}

上記のクエリでは、「user_id」フィールドで「user-x」の値が見つかりません。

{
	"query": {
		"bool": {
			"filter": [{
				"term": {
					"user_id":"user"
				}
			}]
		}
	}
}

代わりに、上記のクエリで user-x を見つけることができます。

理由:

es のバージョン 5.0 以降では、文字列の型がテキストとキーワードの 2 種類に分けられ、前者は分割されてからインデックスが作成されますが、後者は分割されず、完全な文字列が直接インデックスになります。

公式説明:

Keyword datatype
A field to index structured content such as email addresses, hostnames, status codes, zip codes or tags.
They are typically used for filtering (Find me all blog posts where status is published), for sorting, and for aggregations. Keyword fields are only searchable by their exact value.
If you need to index full text content such as email bodies or product descriptions, it is likely that you should rather use a text field.

理由はわかりませんが、バージョン 6.x 以降のキーワードには当てはまりません。元のテキスト データは引き続き単語分割によって処理されますが、完全な文字を保持するために追加のキーワード属性が作成されます。

単語分割を行わずに元のデータを検索する場合は、元のキーの後に .keyword を追加し、正確な一致を実現するために key.keyword を比較する必要があります。

{
	"query": {
		"bool": {
			"filter": [{
				"term": {
					"user_id.keyword":"user-x"
				}
			}]
		}
	}
}

このデザインは単に反人間的なものであり、私はそのようなデザインに何の利点も期待していませんでした。また、リソースを浪費する無駄な単語分割データが大量に発生することになるため、単語分割が必要ない場合は es を使用する必要がありますか? これは魂の奥深い質問です。

おすすめ

転載: blog.csdn.net/sm9sun/article/details/109070081