Elasticsearch のデータ構造

Elasticsearch のクエリで利用する、データ構造をまとめました。

     indexdoc_valuesfielddataglobal_ordinals
用途検索sort/集計/scriptsort/集計/scriptパフォーマンス向上
フィールドほとんど全てtext 以外ほぼ全てtexttext, keyword など
格納場所ストレージストレージヒープメモリヒープメモリ
キャッシュファイルシステムキャッシュファイルシステムキャッシュフィールドデータキャッシュフィールドデータキャッシュ
デフォルト有効有効無効有効※
※ eager_global_ordinals は無効

これらの [用途] で使わないフィールドは、無効にすることでリソース消費を削減できます。

Elasticsearch & OpenSearch の使い方
学習ロードマップ
スポンサーリンク

データ構造の種類

  • index
  • doc_values
  • fielddata
  • global_ordinals

index

index とは、検索で利用するストレージ上のデータ構造です。

analyzer の後に indexe を作成します。

PUT index
{
  "mappings": {
    "properties": {
      "test_field": { 
        "type":  "text",
        "index": false
      }
    }
  }
}

index を無効にすると、インデックスが作成されず、検索できないことを確かめます。

PUT index/_doc/1
{
  "test_field":"Elasticsearch"
}
GET index/_search
{
  "query": {
    "match": {
      "test_field": "Elasticsearch"
    }
  }
}
"type": "query_shard_exception",
"reason": "failed (中略) since it is not indexed.",

インデックスが無いと、検索できないことを確認できました。

doc_values

doc_values とは、ソート・集計・script で利用するストレージ上のデータ構造です。

doc_values を無効にすると、集計できないことを確かめます。

PUT doc_values
{
  "mappings": {
    "properties": {
      "num": { 
        "type":  "integer",
        "doc_values": false
      }
    }
  }
}
POST doc_values/_bulk
{ "index": { "_id": "1" } }
{ "num":1 }
{ "index": {"_id": "2" } }
{ "num":2 }
{ "index": { "_id": "3" } }
{ "num":3 }
GET doc_values/_search
{
  "size": 0,
  "aggs": {
    "result": {
      "avg": {
        "field":"num"
      }
    }
  }
}
"reason": "(中略) Use doc values instead."

doc_values が無効なので、集計できなくなりました

fielddata

fielddata とは、ソート・集計・script で利用するメモリ上のデータ構造です。
text フィールドタイプ専用のデータ構造です。

元々は全てのフィールドタイプで fielddata を利用していたが、メモリを食いすぎるため、ストレージ上にデータを置く doc_values が開発された経緯があるようです。(詳しくはこちら)

fielddata を有効にすることで、text フィールドでも集計可能になります。

PUT fielddata
{
  "mappings": {
    "properties": {
      "str": { 
        "type":  "text",
        "fielddata": true
      }
    }
  }
}
POST fielddata/_bulk
{ "index": { "_id": "1" } }
{ "str":"Elasticsearch is full search engine" }
{ "index": {"_id": "2" } }
{ "str":"Elasticsearch search a doc" }
{ "index": { "_id": "3" } }
{ "str":"Elasticsearch aggrigation terms" }
GET fielddata/_search?size=0
{
  "aggs": {
    "tags": {
      "terms": {
        "field": "str",
        "min_doc_count": 2
      } 
    }
  }
}
      "buckets": [
        {
          "key": "elasticsearch",
          "doc_count": 3
        },
        {
          "key": "search",
          "doc_count": 2
        }

fielddata を有効にすることで、text フィールドでも集計できました

global_ordinals

ordinals (グローバル序数) とは とは、doc values の代わりに順番に割り当てた数字です。

Elasticsearch は、doc values の代わりに、コンパクトな序数をヒープメモリに置き、パフォーマンスを向上させます。

Doc IDdoc values序数
1Elasticsearch1
2OpenSearch2
3Elasticsearch1
同じ用語には同じ序数。
カーディナリが高いほど序数と用語のマッピングが増えるので、メモリ消費が増える

eager_global_ordinals

eager_global_ordinals とは、ordinals (序数) のマッピングを構築するタイミングを決めるパラメータです。
  • true: シャードrefresh する際に ordinals (序数) のマッピングを構築
  • false: 検索で必要な時に ordinals (序数) のマッピングを構築

つまり、true にすると検索が早くなります。(refresh は遅くなります)

PUT ordinals
{
  "mappings": {
    "properties": {
      "str": { 
        "type":  "keyword",
        "eager_global_ordinals": true
      }
    }
  }
}
スポンサーリンク

関連記事

Elasticsearch & OpenSearch の使い方
学習ロードマップ

参考サイト

Elasticsearch: Understanding the Terms Aggregation
Anyone who has worked extensively around Elasticsearch is familiar with terms aggregations. Conceptually, it’s very simple to understand.