ElasticSearchメモ
ElasticSearchのスキーマからHTTP Clientを自動生成とかできたりしたら便利??
elastic searchのインターフェイス
- データ投入
- PUT /${index_name}/_bulk
- POST /${index_name}/_doc
- データ参照
- GET /${index_name}/_search
- https://www.elastic.co/guide/en/elasticsearch/reference/current/search-search.html
- .hits.hits[]._source が実際にインデックスに登録されているデータ
- filedsクエリを使うと、jq '.hits.hits[].fields' となって、レスポンスのフィールドが変わる
- 非構造化データをruntime_mappingsという機能を使って構造化データとして検索できる
- GET /${index_name}/_search
- データ削除
- DELETE /_data_stream/logs-my_app-default
- マッピング
- PUT /${index_name}/_mapping
参考資料
基本概念
indexとは
インデックスは最適化されたドキュメントのコレクションと考えることができ、各ドキュメントはデータを含むキーと値のペアであるフィールドのコレクションです。
documentとは
ユーザーが保存するデータのこと
engineとは
8.2.0以降、Elastic Enterprise Searchでは、既存のElasticsearchインデックスを元にEngineを生成することができるようになりました。これらのエンジンを利用することで、Elasticsearchに取り込まれたデータに対してEnterprise Searchの機能を利用することができます。
Enterprise Searchがどんなことできるのかは別途調査必要。
tips
- ドキュメントを生成するためのツール一覧
-
コンテンツ検索をより良くするためのツール一覧
- facet, コンテンツ検索とかに触れている
- Engineの利用が必須なものが多く、Enterprise APIが必要そう
- 検索結果の改善に便利なツール一覧
- Elastic公式のGolangクライアント
検索エンジンは以下二つの役割がある。
- Indexing
- Searching
ESはIndexごとに明示的なマッピングを行う。マッピング ≒ スキーマのこと。
マッピングをしない場合、作成されるドキュメントから類推してくれる。
データ型
基本的なデータタイプ
データタイプの概念
family has many types
boolean familyにはboolean型だけがある。
keyword familyにはkeyword, constant_keyword, wildcardの3つの型がある。
みたいな感じ。
よく使いそうなやつ
- boolean
- keywords
- keyword
- term level queryで利用されるフィールド
- 完全一致検索のために使われる
- constant_keyword
- 常に同じ値が入るときに使われる
- wildcard
- 大きな値やカーディナリティが高いフィールドに最適化されている
- keyword
- numbers
- たくさんデータ型がある
- 数値系
- dates
- 内部的にはunixtimeで保存される
- date
- date_nanos
- alias
- 特定のフィールドの代わりの名前として使える
- object
- text
- text
- メール本文や商品説明に使える
- text_match_only
- text
- completion
- オートコンプリートに最適化されたタイプ
- クエリについても詳しく書かれている
- search_as_you_type
- 前方一致 or 文中一致による補完をするためのタイプ
- ranking
- いまいち分からん
- Arrays
- 同じ型の要素を0つ以上格納できる
- Multi-fields
-
同じフィールドでも、目的に応じて異なる方法でインデックスを作成すると便利なことが多い。例えば、文字列フィールドを、全文検索ではテキストフィールドとして、ソートや集計ではキーワードフィールドとしてマッピングすることができます。あるいは、標準アナライザ、英語アナライザ、フランス語アナライザでテキストフィールドのインデックスを作成することもできます。これがマルチフィールドの目的です。ほとんどのフィールド・タイプは、fieldsパラメータによってマルチフィールドをサポートしています。
-
データ型毎にマッピング作成時のオプションがある。
keyword型はこれ。
Query DSL
Query DSLは以下2つがある。
- leaf query clauses
-
leaf query clausesは、mathc, term, rangeクエリのように、特定のフィールドの特定の値を探します。これらのクエリは単独で使用することもできます。
-
- compound query clauses
-
compound query clausesは、他のleafクエリやcompoundクエリをラップし、複数のクエリを論理的に組み合わせたり(boolクエリやdis_maxクエリなど)、それらの動作を変更したり(constant_scoreクエリなど)するために使用されます。
-
また、いくつかのクエリは実行コストが高く、クラスタの安定性に影響を与える。
Query and filter context
Query Contextとは
Query Contextでは、Query clauseが "このdocumentはこのQuery clauseにどの程度マッチするか?"という質問に答える。documentがマッチするかどうかを決定するほかに、Query clauseは_scoreメタデータ・フィールドで関連性スコアも計算する。
Query Contextは、Search APIのクエリパラメータのように、Query clausesがクエリパラメータに渡されるたびに有効になります。
検索条件に対してどの程度ドキュメントが合致するのか、スコアを計算する。ドキュメントはこのスコアに応じて並び替えが行われる。
Filter Contextとは
Filter Contextでは、Query clauseは "このdocumentはこのQuery clauseにマッチしますか?"という質問に答えます。答えは単純なYesかNoで、スコアは計算されません。Filter contextは、構造化されたデータをフィルタリングするために使われます。
スコアは計算されない、つまりドキュメントの並び順には影響を与えない。
Compound Queries
bool query
今までboolっていうのがどういう意味なのか分からなかったが、どうもApache Luceneではboolean operatorとしてboolという単語が使われている。つまり、True/Falseといったデータ型というより、論理演算みたいな意味で使われる。
それを踏まえてbool queryを読んでみる。
boolクエリはmore-matches-is-betterアプローチをとるので、マッチしたmust句またはshould句のスコアが加算され、各文書の最終的な_スコアになります。
見た感じだけど、
query.${query_name}.${occur}.${term_level_query}...
っていう構造っぽい?
- query_name
- boolはここに分類される
- occur
- must, must_not, should, filterはここに分類される
- term level query
- term, rangeなどはここに分類される
クエリ例
POST _search
{
"query": {
"bool" : {
"must" : {
"term" : { "user.id" : "kimchy" }
},
"filter": {
"term" : { "tags" : "production" }
},
"must_not" : {
"range" : {
"age" : { "gte" : 10, "lte" : 20 }
}
},
"should" : [
{ "term" : { "tags" : "env1" } },
{ "term" : { "tags" : "deployed" } }
],
"minimum_should_match" : 1,
"boost" : 1.0
}
}
}
must
mustに指定されたクエリがドキュメント内に出現しないといけない、また出現度合いがスコアの計算に影響を与える。
shoud
mustに指定されたクエリがドキュメント内に出現するはず。
mustとの違いは何?
スコアへの影響度合い?
must_not
clause(query)はマッチする文書に現れてはならない。clauseはfilter contextで実行されます。つまり、スコアリングは無視され、clauseはキャッシュの対象となります。スコアリングは無視されるため、すべてのドキュメントに対してスコア0が返されます。
must_notとmustを組み合わせたりすると、スコアはどうなるんだ?
filter
clause(query)はマッチした文書に登場しなければならない。しかし、mustとは異なり、クエリのスコアは無視されます。つまり、スコアリングは無視され、clauseはキャッシュの対象となります。filter contextで実行される。
boosting
postiveクエリにマッチする文書を返す一方で、negativeクエリにもマッチする文書の関連性スコアを下げる。
検索結果から除外することなく、特定の文書を降格させるためにブーストクエリを使用することができます。
positive
negative
constant_score
dis_max
function_score
term level query
用語レベルクエリを使用すると、構造化データの正確な値に基づいてドキュメントを検索できます。構造化データの例としては、日付範囲、IPアドレス、価格、製品IDなどがあります。
フルテキスト・クエリとは異なり、用語レベル・クエリは検索用語を分析しません。その代わりに、用語レベルクエリはフィールドに保存されている用語を正確にマッチさせる。
タグやカテゴリIDの完全一致とかの検索に使えそう。