Open7

ElasticSearchメモ

koheiyamayamakoheiyamayama

ElasticSearchのスキーマからHTTP Clientを自動生成とかできたりしたら便利??

koheiyamayamakoheiyamayama

elastic searchのインターフェイス

  • データ投入
    • PUT /${index_name}/_bulk
    • POST /${index_name}/_doc
  • データ参照
    • GET /${index_name}/_search
  • データ削除
    • DELETE /_data_stream/logs-my_app-default
  • マッピング
    • PUT /${index_name}/_mapping

参考資料

koheiyamayamakoheiyamayama

基本概念

https://www.elastic.co/guide/en/enterprise-search/current/start.html

indexとは

インデックスは最適化されたドキュメントのコレクションと考えることができ、各ドキュメントはデータを含むキーと値のペアであるフィールドのコレクションです。

documentとは

ユーザーが保存するデータのこと

engineとは

https://www.elastic.co/guide/en/app-search/current/elasticsearch-engines.html

8.2.0以降、Elastic Enterprise Searchでは、既存のElasticsearchインデックスを元にEngineを生成することができるようになりました。これらのエンジンを利用することで、Elasticsearchに取り込まれたデータに対してEnterprise Searchの機能を利用することができます。

Enterprise Searchがどんなことできるのかは別途調査必要。

koheiyamayamakoheiyamayama

検索エンジンは以下二つの役割がある。

  • Indexing
  • Searching

ESはIndexごとに明示的なマッピングを行う。マッピング ≒ スキーマのこと。
マッピングをしない場合、作成されるドキュメントから類推してくれる。

koheiyamayamakoheiyamayama

データ型

基本的なデータタイプ
https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping-types.html

データタイプの概念
family has many types
boolean familyにはboolean型だけがある。
keyword familyにはkeyword, constant_keyword, wildcardの3つの型がある。

みたいな感じ。

よく使いそうなやつ

  • boolean
  • keywords
    • keyword
      • term level queryで利用されるフィールド
      • 完全一致検索のために使われる
    • constant_keyword
      • 常に同じ値が入るときに使われる
    • wildcard
      • 大きな値やカーディナリティが高いフィールドに最適化されている
  • numbers
    • たくさんデータ型がある
    • 数値系
  • dates
    • 内部的にはunixtimeで保存される
    • date
    • date_nanos
  • alias
    • 特定のフィールドの代わりの名前として使える
  • object
  • text
    • text
      • メール本文や商品説明に使える
    • text_match_only
  • completion
    • オートコンプリートに最適化されたタイプ
    • クエリについても詳しく書かれている
  • search_as_you_type
    • 前方一致 or 文中一致による補完をするためのタイプ
  • ranking
    • いまいち分からん
  • Arrays
    • 同じ型の要素を0つ以上格納できる
  • Multi-fields
    • 同じフィールドでも、目的に応じて異なる方法でインデックスを作成すると便利なことが多い。例えば、文字列フィールドを、全文検索ではテキストフィールドとして、ソートや集計ではキーワードフィールドとしてマッピングすることができます。あるいは、標準アナライザ、英語アナライザ、フランス語アナライザでテキストフィールドのインデックスを作成することもできます。これがマルチフィールドの目的です。ほとんどのフィールド・タイプは、fieldsパラメータによってマルチフィールドをサポートしています。

データ型毎にマッピング作成時のオプションがある。
keyword型はこれ。
https://www.elastic.co/guide/en/elasticsearch/reference/current/keyword.html#keyword-params

koheiyamayamakoheiyamayama

Query DSL

https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl.html

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

https://www.elastic.co/guide/en/elasticsearch/reference/current/term-level-queries.html

用語レベルクエリを使用すると、構造化データの正確な値に基づいてドキュメントを検索できます。構造化データの例としては、日付範囲、IPアドレス、価格、製品IDなどがあります。
フルテキスト・クエリとは異なり、用語レベル・クエリは検索用語を分析しません。その代わりに、用語レベルクエリはフィールドに保存されている用語を正確にマッチさせる。

タグやカテゴリIDの完全一致とかの検索に使えそう。