Elasticsearch マッピング管理 + テンプレート

マッピング管理 + テンプレート

マッピング(Mapping)は、前述のとおりフィールドの Key の形を定義したものである。一度作成したマッピングは、フィールド追加を除いて修正できない。修正するにはインデックスを作り直す必要がある。

マッピングを作成および追加する方法は、次の 4 つである。

  • 自動でマッピングを作成する
  • 手動でマッピングを作成する
  • テンプレートでマッピングを作成する
  • 既存のマッピングにフィールドを追加する

自動でマッピングを作成する

Elasticsearch は、次のようにインデックスにドキュメントを作成するとき、自動でマッピングを作成する。

mapping_test インデックスにドキュメントを作成

PUT /mapping_test/_doc/1
{
  "date":"2021/12/01 09:00:00+0900",
  "Tweet":"This is a mapping test."
}

マッピング確認

GET /mapping_test

マッピング内容

GET /mapping_test
{
  "mapping_test" : {
    "aliases" : { },
    "mappings" : {
      "properties" : {
        "Tweet" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        },
        "date" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        }
      }
    },

// ... 以下省略 ...

上記の結果を見ると、次のようなマッピングが定義されたことがわかる。text 型と keyword 型の違いについては次のとおりである。

  • dateTweet キーは text
  • date.keywordtext.keyword キーは keyword

上記で作成したマッピングの date キーは text 型として登録されているが、date 型として登録しなければならない場合がある。そのような場合は、手動でマッピングを作成する必要がある。

手動でマッピングを作成する

手動でマッピングを作成する方法は次のとおりである。

手動マッピングを作成

PUT /mapping_test2
{
  "mappings": {
    "properties": {
      "date":    { 
        "type": "date",
        "format": "yyyy/MM/dd HH:mm:ssZ"
      },  
      "tweet":  {
        "type": "text",
        "fields": {
          "keyword":{
            "type":"keyword"
          }
        }
      }
    }
  }
}

手動でマッピングを作成した結果

GET /mapping_test2

手動で作成したマッピング内容

GET /mapping_test2
{
  "mapping_test2" : {
    "aliases" : { },
    "mappings" : {
      "properties" : {
        "date" : {
          "type" : "date",
          "format" : "yyyy/MM/dd HH:mm:ssZ"
        },
        "tweet" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword"
            }
          }
        }
      }
    },

... 以下省略 ...

正しく作成できていれば、date キーが date 型としてマッピングされていることがわかる。

マッピングで指定したフォーマットと異なる場合

マッピングで指定した形式と異なるドキュメントを作成するとエラーが発生する。

実行してみると、date フィールドのフォーマットは "yyyy/MM/dd HH:mm:ssZ" だが、別フォーマットとして "yyyy/MM/dd HH:mm:Z"(秒を指定していない)データを入れてみる。

マッピングで指定したフォーマットと異なるドキュメントを作成

PUT /mapping_test2/_doc/1
{
  "date":"2021/12/01 09:00+0900",
  "tweet":"This is a mapping test."
}

エラーメッセージ

{
  "error" : {
    "root_cause" : [
      {
        "type" : "mapper_parsing_exception",
        "reason" : "failed to parse field [date] of type [date] in document with id '1'. Preview of field's value: '2021/12/01 09:00+0900'"
      }
    ],

... 以下省略 ...

予想どおり、date フィールドを解析できないというメッセージが表示される。

マッピングで指定したフォーマットと同じ場合

今度は正しいフォーマットでドキュメントを作成してみる。

マッピングのフォーマットどおりにドキュメントを作成

PUT /mapping_test2/_doc/2
{
  "date":"2020/11/01 09:00:00+0900",
  "tweet":"This is a mapping test."
}

正しいフォーマットでドキュメントを作成すると成功することがわかる。

テンプレートでマッピングを作成する

インデックスごとに同じマッピングを何度も作成するのは手間がかかる。これを解決するのがテンプレートである。

テンプレートは、指定した名前のインデックスが作成されたときに、テンプレートのマッピングを使ってインデックスを作成する。テンプレートを作成するには template API を使用する。

_template API を使用する。

PUT /_template/test_template
{
  "index_patterns": "test*",
  "mappings": {
    "properties": {
      "date":    { 
        "type": "date",
        "format": "yyyy/MM/dd HH:mm:ssZ"
      },  
      "tweet":  {
        "type": "text",
        "fields": {
          "keyword":{
            "type":"keyword"
          }
        }
      }
    }
  }
}

上記のテンプレートでは、"index_patterns": "test*" と指定しているため、インデックス名の接頭辞に "test" がある場合、指定したマッピングを作成する。

テンプレートの動作を確認してみよう。

test インデックスを作成

PUT /test

test インデックスのマッピング確認

GET /test

test インデックスのマッピング結果確認

GET /test
{
  "test" : {
    "aliases" : { },
    "mappings" : {
      "properties" : {
        "date" : {
          "type" : "date",
          "format" : "yyyy/MM/dd HH:mm:ssZ" // テンプレートで指定した format で date フィールドが登録される
        },
        "tweet" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword"
            }
          }
        }
      }
    },

... 以下省略 ...

テンプレートで指定した format で date フィールドが登録されたことがわかる。

既存マッピングにフィールドを追加する

既存マッピングに新しいフィールドを追加するには mapping API を使用する。

additional_field フィールドを mapping_test2 インデックスのマッピングに追加してみる。

mapping_test2 の内容

GET /mapping_test2
{
  "mapping_test2" : {
    "aliases" : { },
    "mappings" : {
      "properties" : {
        "date" : {
          "type" : "date",
          "format" : "yyyy/MM/dd HH:mm:ssZ"
        },
        "tweet" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword"
            }
          }
        }
      }
    },
... 以下省略 ...

マッピングにフォーマットを追加

PUT /mapping_test2/_mapping
{
  "properties":{
    "additional_field":{
      "type":"text"
    }
  }
}

additional_field フォーマットが追加されたことを確認

GET /mapping_test2

additional_field フォーマットが追加された結果確認

{
  "mapping_test2" : {
    "aliases" : { },
    "mappings" : {
      "properties" : {
        "additional_field" : { // additional_field フィールドが追加された
          "type" : "text"
        },
        "date" : {
          "type" : "date",
          "format" : "yyyy/MM/dd HH:mm:ssZ"
        },
        "tweet" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword"
            }
          }
        }
      }
    },
... 以下省略 ...

additional_field フィールドが追加されたことを確認できた。