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