Elasticsearch(ES)が使いやすい理由の一つとして、スキーマの自動マッピング機能があります
生データを送れば、型を推測してくれるわけです
ただし geo_point などの一部の型は自動マッピングしてくれない、という課題があります
かといって PUT _mapping/INDEX_NAME でスキーマ定義をやるのもスマートじゃないです
解決方法
ESのテンプレート機能を使いましょう
これにより、ESの自動マッピングの一部を上書きできます。それ以外は自動マッピングに任せることができるので、最小限の指定でOKです
テンプレートを使う
- 対象Indexは
my_map_indexから始まるインデックスすべて (例my_map_index0など) - 対象Typeは
waypoints - 対象Fieldは
payloads.dataで、認識する型はgeo_pointとする場合のテンプレートは下記のようになります
{
"template": "my_map_index*",
"mappings": {
"waypoints": {
"properties": {
"payloads": {
"properties": {
"data": {
"type": "geo_point"
}
}
}
}
}
}
}
実際の操作
※最初のDELETEは念のため。操作はお気をつけて
$ curl -X DELETE https://$ES_HOST/my_map_index0
$ curl -X DELETE https://$ES_HOST/_template/my_map_tpl
$ curl -X PUT -H "Content-Type: application/json" -d @- <<EOT https://$ES_HOST/_template/my_map_tpl
{
"template": "my_map_index*",
"mappings": {
"waypoints": {
"properties": {
"payloads": {
"properties": {
"data": {
"type": "geo_point"
}
}
}
}
}
}
}
EOT
データ投入してみる
$ curl -X POST -H "Content-Type: application/json" -d @- <<EOT https://$ES_HOST/my_map_index0/waypoints
{
"payloads": {
"number": 1,
"data": [35.680962, 139.766778]
}
}
EOT
Kibanaでインデックスをつくると、下記の通り payloads.data が geo_point として認識されています。指定が無かった payloads.number は number として自動認識されています
ちなみに geo_point として認識されるフォーマットは複数あります。ドキュメントをご覧ください。ちなみに、配列で渡す場合は [経度, 緯度] の順番ですので、お気を付けください
あとがき
geo_point は認識したけど、肝心の地図が表示されない!というときはこちらをご覧ください
EOT
