Elasticsearchのマッピングでintegerを指定したのに，あっれれ〜stringになってる？問題について

## はじめに
全文検索エンジン[Elasticsearch](https://www.elastic.co/jp/elasticsearch)の勉強を始めて1ヶ月くらいの雑魚エンジニアです．まだまだ理解できていない部分が多いのが現状．．．（変なところあったら，コメント下さい）

今回はタイトルの通り，マッピングでintegerを指定していたのに，stringになっていて，ハマったのでその考察です．
Elasticsearchでは自動で型推論が行われるので，stirngを入れてもintにしてくれる．．．と思っていたのですが，検索をしたときの結果がstirngになっているときがありました．

## 環境
※いずれもDockerで構築
Elasticsearch 7.1.0
kibana 7.1.0

## マッピングを設定
以下のコマンドは全て，kibanaのコンソール上で実行しています．(シェルからcurlコマンドを叩いてもいいのですが，入力しずらいので)

型がintegerで`number_int`というフィールドがあるマッピングを設定しておきます．

```:入力
PUT my_index
{
  "mappings": {
    "properties": {
      "number_int": {
        "type": "integer"
      }
    }
  }
}
```
```:結果
{
  "acknowledged" : true,
  "shards_acknowledged" : true,
  "index" : "my_index"
}
```
![スクリーンショット 2020-03-14 21.45.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294876/52ef1f9a-4f0a-1d39-d691-5aaf4652dd07.png)

## マッピングの確認

正しくマッピングができているか念の為，確認します．

```
GET my_index/_mapping
```

```:結果
{
  "my_index" : {
    "mappings" : {
      "properties" : {
        "number_int" : {
          "type" : "integer"
        }
      }
    }
  }
}
```

![スクリーンショット 2020-03-14 21.45.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294876/3c2fd034-99dc-81b4-f36b-8e1fa0290cb7.png)

(わーい，できてる〜)

## stringのデータを登録してみる
マッピングではintegerとしているのですが，
「型推論が行われるから大丈夫だろ」
と思ったマヌケな僕は，**stringのデータを登録してみます．**

```:入力
PUT my_index/_doc/1
{
  "number_int": "10" 
}
```

```:結果
{
  "_index" : "my_index",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 1,
  "result" : "created",
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 0,
  "_primary_term" : 1
}

```

![スクリーンショット 2020-03-14 21.46.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294876/cc2c4c6b-4c64-73e1-b669-ea66174ed00e.png)

（わーい，無事登録できたよー）

が，しかし．．．

## 検索をかけてみる

`number_int`が20以下で検索をかけてみます．すると(**結果をよく見てください**)

```:入力
GET my_index/_search
{
  "query" : {
    "range" : {
      "number_int" : {
        "lte" : 20
      }
    }
  }
}
```

```:結果
{
  "took" : 663,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "my_index",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 1.0,
        "_source" : {
          "number_int" : "10"
        }
      }
    ]
  }
}
```

![スクリーンショット 2020-03-14 21.42.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294876/3cb6ff64-848d-ff5f-dc41-dfcbb687c7dd.png)

`"number_int" : "10"`となっています．

**マッピングの型はintegerなのにあれ？
string？？？
なんで？？？
型変換してくれないの？？？
検索するときはinteger(20以下の20)にしているのに？？？**

## 試しにintegerのデータを登録してみる
`PUT my_index/_doc/1`だと先ほどのドキュメントを上書きしてしまうため，2に変更しています．

```:入力
PUT my_index/_doc/2
{
  "number_int": 14
}
```

```:結果
{
  "_index" : "my_index",
  "_type" : "_doc",
  "_id" : "2",
  "_version" : 1,
  "result" : "created",
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 3,
  "_primary_term" : 1
}
```

![スクリーンショット 2020-03-14 22.25.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294876/3efea6b6-6835-f830-bea8-c1bc6f9d4cd8.png)

## もう一回，検索をかけてみる

もう一度，`number_int`が20以下で検索してみます．
すると．．．


```:入力
GET my_index/_search
{
  "query" : {
    "range" : {
      "number_int" : {
        "lte" : 20
      }
    }
  }
}
```

```:結果
{
  "took" : 550,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 2,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "my_index",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 1.0,
        "_source" : {
          "number_int" : "10"
        }
      },
      {
        "_index" : "my_index",
        "_type" : "_doc",
        "_id" : "2",
        "_score" : 1.0,
        "_source" : {
          "number_int" : 14
        }
      }
    ]
  }
}

```

![スクリーンショット 2020-03-14 22.26.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294876/95974cc8-1666-1a76-8302-a1cb550198f1.png)

`"_id" : "1"`の方は`"number_int" : "10"`と先ほどと変わらずstringのままで，`"_id" : "2",`の方は，`"number_int" : 14`とintegerになっています．

もはや，わけわかめー

## どうやら，`_source` field は，インデックス保存時に渡された値を返しているらしい
最初，Elastcisearchの公式が最も情報量が豊富なので探してみたのですが，よくわかりませんでした．

というわけで，ゴリ押しでググりまくって見つけました．

参考 : [今日のElasticsearch学び Vol.2 - Mappings編]
(https://blog.shibayu36.org/entry/2016/08/03/110000)

> _source fieldには実際に投入したドキュメントのそのままの値が入っている。つまりCharFilterとかTokenizerとかそういうのが全くかかっていない状態のものが入っている。詳しくは_source fieldを参照。

どうやら`_source` field の仕様のようです(マッピングが間違えているとばかり思っていました．．．)．公式のリンクも貼ってくださっていたので，みてみます．


参考(公式) : [_source field](https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping-source-field.html)

> The _source field contains the original JSON document body that was passed at index time.

ということから，ドキュメントとして登録されているのは型を自動で変換して，integerになっているが，
**`_source` fieldに含まれるのは，インデックス保存時に渡された値なので，stringで返ってきたり，integerで返ってきていたみたいです．**

Elasticsearchを扱うときは型に気をつけましょう〜