ELK-20180411-我竟不知道 mappings 的重要性

Problem

# 純小數計算 avg,結果不正確
curl -XGET http://ES_URL:9200/ES_INDEX/ES_TYPE/_search -d '
  {
    "query": {
      "bool": {
        "must": [
          {
            "query_string": {
              "query": "xxx",
              "analyze_wildcard": true
            }
          },
          {
            "range": {
              "orig_timestamp": {
                "gte": "2018-04-11T10:11:35+08:00",
                "lte": "2018-04-11T15:11:35+08:00"
              }
            }
          }
        ],
        "must_not": []
      }
    },
    "sort": [
      {
        "orig_timestamp": "asc"
      }
    ],
    "aggs": {
      "time": {
        "date_histogram": {
          "field": "orig_timestamp",
          "interval": "1h",
          "time_zone": "Asia/Shanghai",
          "min_doc_count": 3
        },
        "aggs": {
          "success_rate": {
            "stats": {
              "field": "hourly_success_rate"
            }
          }
        }
      },
      "error_rate": {
        "stats": {
          "field": "hourly_error_rate"
        }
      }
    },
    "timeout": "300s",
    "size": 30
  }'

然後 aggs 中 sum/avg/stats 對純小數取出的計算結果總是做了取整計算。
問題大概同 aggs的sum 求和後數值只有整數部分,小數部分都沒了

Solution

其實是因爲 mappings,利用如下命令可以看到 mappings 信息。

curl -XGET http://ES_URL:9200/ES_INDEX/_mappings
{
	"ES_INDEX": {
		"mappings": {
			"ES_TYPE": {
				"properties": {
					"hourly_error_rate": {
						"type": "long"
					},
					"hourly_success_rate": {
						"type": "long"
					}
				}
			}
		}
	}
}

結果,可以看到這個純小數所在的字段 field 的映射類型 type 是 long 長整型。
假設第一個塞進該字段的數是 1,那麼他映射爲 long 長整型,然後即便之後塞進去的數字都是 float 浮點數類型,但是取出來做 avg 的時候,它內部應該是先拿到 mappings,根據 mapping 定義臨時變量,然後計算。那麼,0.5 變成 long 型,就取整成了 0。假設原來需要計算 (0.19+0.51+1)/3,那麼就變成了 (0+0+1)/3=0.33333,悲劇就是這麼產生的。

想要規避這個問題,純靠保持第一個錄入的數據正確還是不太保險。最好是自己寫 create index 之後加入 mappings 信息,或者用 template 也可以。
總之就是最保險的方案就是需要提前定義字段映射信息,保證 index 的映射元數據是正確的。

Reference

Incorrect sum while aggregating in elasticsearch for one particular index

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章