Elasticsearchのobjectタイプとダイナミックマッピング

5847 ワード

議論すべき最後の自然JSONデータ型はオブジェクト(object)である.他の言語ではhash、hashmap、dictionary、associative arrayと呼ばれている.
内部オブジェクト(inner objects)は、別のオブジェクトにエンティティまたはオブジェクトを埋め込むためによく使用されます.たとえば、tweetドキュメントのuser_nameuser_idの代わりに、次のように書くことができます.
{
    "tweet":            "Elasticsearch is very flexible",
    "user": {
        "id":           "@johnsmith",
        "gender":       "male",
        "age":          26,
        "name": {
            "full":     "John Smith",
            "first":    "John",
            "last":     "Smith"
        }
    }
}

内部オブジェクトのマッピング
Elasticsearchは、新しいオブジェクトのフィールドを動的に検出し、objectタイプにマッピングし、各フィールドをpropertiesフィールドに追加します.
{
  "gb": {
    "tweet": { <1>
      "properties": {
        "tweet":            { "type": "string" },
        "user": { <2>
          "type":             "object",
          "properties": {
            "id":           { "type": "string" },
            "gender":       { "type": "string" },
            "age":          { "type": "long"   },
            "name":   { <3>
              "type":         "object",
              "properties": {
                "full":     { "type": "string" },
                "first":    { "type": "string" },
                "last":     { "type": "string" }
              }
            }
          }
        }
      }
    }
  }
}

<1>ルートオブジェクト.
<2><3>内部オブジェクト.userおよびnameフィールドのマッピングは、tweetタイプ自体と類似している.実際、typeマッピングはobjectマッピングの特殊なタイプにすぎず、objectをルートオブジェクトと呼ぶ._source_allなどの特殊な最上位フィールドがない限り、他のオブジェクトと同じです.
内部オブジェクトがどのようにインデックスされているか
Luceneは内部オブジェクトを知らない.1つのLuceneファイルには、キー値に対応するフラットフォームが含まれています.Elasticsearchが内部オブジェクトを効率的にインデックスできるように、ファイルを次の形式に変換します.
{
    "tweet":            [elasticsearch, flexible, very],
    "user.id":          [@johnsmith],
    "user.gender":      [male],
    "user.age":         [26],
    "user.name.full":   [john, smith],
    "user.name.first":  [john],
    "user.name.last":   [smith]
}

内部カラムは、例えば"first"のようなnameに分類することができる.同じ名前の2つの欄を区別するために、"user.name.first"または の名前にパス:"tweet.user.name.first"を追加するなど、完全なパスを使用することができます.
注意:以上の扁平化ファイルでは、userという欄もuser.nameという欄もありません.Luceneは階層または単純な値のみをインデックスし、複雑な資料構造をインデックスしません.
ダイナミックマッピング
Elasticsearchは、位置のフィールドを処理する場合、「動的マッピング」によってフィールドのデータ型を決定し、そのフィールドをタイプマッピングに自動的に追加します.
時には理想的な行為だが、時にはそうではない.今後どのフィールドがドキュメントに追加されるか分からないかもしれませんが、自動的にインデックスされることを望んでいます.無視したいだけかもしれません特に、Elasticsearchをプライマリ・データ・ソースとして使用する場合は、未知のフィールドに異常を投げ出して警告することを望んでいます.
幸いなことに、dynamicの設定でこれらの動作を制御することができます.以下のオプションを受け入れることができます.true:フィールドの自動追加(デフォルト)false:フィールドを無視strict:不明なフィールドに遭遇したときに例外を放出dynamicの設定は、ルートオブジェクトまたは任意のobjectオブジェクトで使用できます.dynamicstrictにデフォルト設定し、特定の内部オブジェクトで有効にすることができます.
PUT /my_index
{
    "mappings": {
        "my_type": {
            "dynamic":      "strict", <1>
            "properties": {
                "title":  { "type": "string"},
                "stash":  {
                    "type":     "object",
                    "dynamic":  true <2>
                }
            }
        }
    }
}

<1>不明なフィールドに遭遇すると、my_typeオブジェクトが例外を放出します.
<2>stashオブジェクトは自動的にフィールドを作成します
このマッピングにより、stashオブジェクトに新しい検索可能フィールドを追加できます.
PUT /my_index/my_type/1
{
    "title":   "This doc adds a new field",
    "stash": { "new_field": "Success!" }
}

しかし、最上位レベルで同じ操作をすると失敗します.
PUT /my_index/my_type/1
{
    "title":     "This throws a StrictDynamicMappingException",
    "new_field": "Fail!"
}

注記:dynamicfalseに設定しても、_sourceフィールドの内容はまったく変更されません._sourceは、インデックスを保持するときの完全なJSONドキュメントを保持します.ただし、マッピングに追加されていない未知のフィールドは検索できません.
+