Elasticsearch-headで.rawの付いたフィールド名を表示するには

前回 、「kibanaで.rawの付いたフィールド名を表示するには」のご質問をして回答を頂いて解決しましたが、

マルチフィールドで生成されるフィールド
( ここでは .raw の付いたフィールドで、以下 name.raw と明記します)
は、
元のフィールド
( ここでは .raw の付いていないフィールドで、以下 name と明記します)
と同じように、
elasticsearchのデータベースの中に作成されて、
name と name.raw の2つのフィールドが存在しているのでしょうか。

elasticsearch-headは、デフォルトでは name のフィールドしか表示されていませんが、
name.raw のフィールドも表示させることはできるでしょうか。

curlコマンドのドキュメントの取得でも、name のフィールドしか表示されていませんが、
name.raw のフィールドも表示させることはできるでしょうか。

よろしくお願いします。

1 Like

「表示されない」というのは、どの部分に表示されないという意味でしょうか?
_sourceにないという意味であれば、そこには登録したJSONにある項目しか出てこないです。

参考:https://www.elastic.co/guide/en/elasticsearch/guide/current/document.html

質問の内容が分かりにくくて申し訳ありません。

Fig1


「表示されない」というのは、どの部分に表示されないという意味でしょうか?

上記 Fig1 の赤色の部分に name.raw が表示されていないという意味です。


_sourceにないという意味であれば、そこには登録したJSONにある項目しか出てこないです。

Fig1 に、
_index , _type , _id , _score はありますが、
_source が見当たりませんがどこにあるのでしょうか。
( _source を表示するにはどのようにすればよろしいでしょうか )

なお、Fig1 を表示するために行った内容を以下に示しておきます。

よろしくお願いします。


下記 (1) でマルチフィールドの設定をして、
下記 (2) でドキュメントを書き込みます。

( このマルチフィールドの設定とドキュメントの書き込みで、
name フィールドの他に name.raw フィールドもできている
と思っていますが正しいでしょうか )

elasticsearch-head プラグインで確認すると、
name フィールドは表示されていますが
name.raw フィールドが見当たりません ( Fig1 参照 )

下記 (3) でドキュメントを取得しても、
name フィールドはありますが、
name.raw フィールドは見当たりません。

(1) マルチフィールドの設定
curl -XPUT http://localhost:9200/index_name?pretty=1 -d @m.json
---m.json--------------------------------------------------------

{
  "mappings" : {
    "mapping_name" : {
      "properties" : {
        "name" : {
          "type" : "multi_field",
          "fields" : {
            "name" : {"type" : "string"},
            "raw" : {"type" : "string","index" : "not_analyzed"}
          }
        }
      }
    }
  }
}

(2) ドキュメントの書き込み
curl -X PUT http://localhost:9200/index_name/type_name/1?pretty=1 -d "{"name": "yama","value": 123}"

(3) ドキュメントの確認
curl -XGET http://localhost:9200/index_name/type_name/1?pretty=1
--- (3) のレスポンス --------------

{
  "_index" : "index_name",
  "_type" : "type_name",
  "_id" : "1",
  "_version" : 1,
  "found" : true,
  "_source" : {
    "name" : "yama",
    "value" : 123
  }
}

(1)で指定しているタイプ名(mapping_name)と(2)で登録しているデータのタイプ名(type_name)が異なるので、マッピングの指定が効かないですね。

headの利用方法(_sourceの表示)についてはheadのリポジトリで質問するのが良いかと。

(1)で指定しているマッピング名(mapping_name)と(2)で登録しているデータのマッピング名(type_name)が異なるので、マッピングの指定が効かないですね。

よく分からなくなってきたのですが、私の認識では、
(1) の mapping_name は マッピング名で、
(2) の type_name はマッピング名ではなくタイプ名
と理解していたのですが間違っていますでしょうか。
また、この両者を一致させないとマッピングの指定が効かない
というのは正しいでしょうか。

というのも、この設定 (1) (2) の後、kibana で確認してみると、
Fig2 のように、kibanaでは、name だけでなく name.raw も表示されていて、
このマッピングの設定が効いているように見えるのですが・・・

念のため、両者を一致させて、
つまり、(2) の type_name を (1) の mapping_name に変更して、
(2') curl -X PUT http://localhost:9200/index_name/mapping_name/1?pretty=1 -d "{"name": "yama","value": 123}"
を実行して確認してみたのですが、
変更前 ( type_name ) の時と同じ結果でした。

よろしくお願いします。

Fig2

あぁ、タイプ名ですね。治しておきます。
タイプごとにマッピングがことなります。
ただし、Kibanaではインデックスまでしか指定をしないので、インデックス配下にあるすべてのフィールドが表示されます。

変化がないのはすでにマッピングが決まっているものなので、変更できないからです。こちらをご覧ください
https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping.html#_updating_existing_mappings

回答ありがとうございます。

回答の中で、

変化がないのはすでにマッピングが決まっているものなので、変更できないからです。こちらをご覧ください
Mapping | Elasticsearch Guide [8.11] | Elastic

の 「変更できない」 という部分ですが、
このマッピングの設定を削除して、インデックスも削除して、
まっさらの状態から、再度設定をし直せば、
変更できるという意味でよろしいでしょうか。

例えば、
curl -X DELETE localhost:9200/index_name/_mapping/mapping_name?pretty=1
でマッピングの設定を削除して、
index_nameのインデックスも削除して、
下記 (1) (2') (3') を実行してみたのですが、
それでも、elasticsearch-head プラグインでも、
(3') のレスポンスでも、name.raw は表示されていませんが、
どこか間違っていますでしょうか。

よろしくお願いします。

(1) curl -XPUT http://localhost:9200/index_name?pretty=1 -d @m.json
---m.json--------------------------------------------------------

{
  "mappings" : {
    "mapping_name" : {
      "properties" : {
        "name" : {
          "type" : "multi_field",
          "fields" : {
            "name" : {"type" : "string"},
            "raw" : {"type" : "string","index" : "not_analyzed"}
          }
        }
      }
    }
  }
}

(2') curl -X PUT http://localhost:9200/index_name/mapping_name/1?pretty=1 -d "{"name": "yama","value": 123}"

(3') curl -XGET http://localhost:9200/index_name/mapping_name/1?pretty=1

---(3') のレスポンス-----------

{
  "_index" : "index_name",
  "_type" : "mapping_name",
  "_id" : "1",
  "_version" : 1,
  "found" : true,
  "_source" : {
    "name" : "yama",
    "value" : 123
  }
}

はい。可能です。

前にも回答していますが、_sourceには、登録したJSONが そのまま 保存されます。
mappingで指定しているのは、検索などで利用するフィールドの定義です。
これは、登録に使用したJSONの値をもとにして、Mappingで指定されたフィールドのタイプなどをもとに検索やAggsで利用できるようにElasticsearchに指定するものになります。

さらに補足です。 The Root Object | Elasticsearch: The Definitive Guide [2.x] | Elastic

回答ありがとうございます。

まったく基本的なことがよく分からないのですが・・・

(疑問点1)
_sourceを取得するにはどのようにすればよいのでしょか。
もしよろしければ、
curl -XGET http://localhost:9200/index_name/mapping_name/1?pretty=1
というように、
上記の例で実行する具体的なコマンドを教えていただけないでしょうか。

(疑問点2)
(3') curl -XGET http://localhost:9200/index_name/mapping_name/1?pretty=1
で取得したレスポンスの中の_sourceの{ }の中の部分が_sourceになるのでしょうか。
もし、これが正しいとすると、
_sourceの中にname.rawがなかった場合、
Elasticsearchにはname.rawのフィールドが存在しないということなのでしょうか。

(疑問点3)
_sourceの中にname.rawがなかった場合は、
curlでname.rawを取得することはできないのでしょうか。
もし、これが正しいとすると、
kibanaではname.rawが表示されていますが、
なぜ、kibanaではname.rawが取得できているのでしょうか。

あまりに程度の低い質問で申し訳ありませんが、
よろしくお願い致します。

まずは、Getting Started | Elasticsearch: The Definitive Guide [2.x] | Elastic こちらの章を読んでいただくのが良いかと思います。

こちらをご覧ください。

いえ、存在します。。
Mappingで定義するのは、検索に使用するフィールドであり、結果として取得するものではありません。Aggregation(集計など)でも利用されます。
ただし、データを検索した結果や取得した結果には含まれない設定にデフォルトでなっています。
入力した値については、_sourceの中から取り出すのが通常です。

検索に使用されるフィールドは、転置インデックス(Inverted Index)と言う形式で検索に適した形で保存されます。
転置インデックスなどの構造については、こちらをご覧ください。
参考:Mapping and Analysis | Elasticsearch: The Definitive Guide [2.x] | Elastic

上記でも回答しましたが、_sourceからnameを取得すると同じものが入っています。。

以前のマッピングの指定では、次のようになっていました。

この指定の意味は、JSONにあるnameと言うデータを
nameと言うフィールドで Analyzeして 検索できるように転置インデックスを構築し、
name.rawと言うフィールドに Analyzeしない で転置インデックスを構築する(例えば、完全一致、Aggregation、ソートなどに利用するため)。
と言う意味になります。
なので、入力された値としてはnameがそのまま保存されます。ですので、name.rawから値を取得する必要はありません。
KibanaはAggregationと言うElasticsearchの機能を用いて、集計などを行っているために、name.rawを使用します。
AggregationとAnalyzeの関係についてはこちらをご覧ください。

最初は、マルチフィールドで生成されたname.rawが、
正しく生成されているのかどうかを確認したかったため
ご質問をしましたが、
どうも、name.rawを取得する方法がない(取得する必要もない)
というような感触が伝わってきましたので、
将来、このことが理解できるようになるまでは、
このようなものであるということを記憶に留めておきます。
ありがとうございました。

1 Like