iT邦幫忙

第 12 屆 iT 邦幫忙鐵人賽

DAY 6
2
Elastic Stack on Cloud

Elastic 戰台股系列 第 6

[Day06] 資料還是要有點規範 - Mapping

準備往 ES 塞大量資料前,有件事怪怪的,我好像沒有給資料欄位 ( Data Field ) 指定資料型別 ( Data Type ),對比關聯式資料庫,也就是 Schema。在 Elasticsearch 中,是透過 Mapping 來進行。今天就來玩玩 Mapping 吧!

Mapping 的種類

在 Elasticsearch 中,Mapping 分成兩類:

  • Explicit mapping:

    由使用者自行定義的的資料型別

  • Dynamic mapping:

    ES 自動產生

前幾天新建立的 Index,很顯然會是 Dynamic mapping,我 Index 的盤後資訊 Document 如下:

{
  "stock_id":"0050",
  "date":"2020-09-11",
  "volume":2905291,
  "open":103.20,
  "high":103.35,
  "low":102.80,
  "close":103.25
}

讓我們來瞧瞧 ES 如何幫我定義 Data Type。透過以下的 API:

GET /history-prices/_mapping

得到以下的 mapping :

{
  "history-prices" : {
    "mappings" : {
      "properties" : {
        "close" : {
          "type" : "float"
        },
        "date" : {
          "type" : "date"
        },
        "high" : {
          "type" : "float"
        },
        "low" : {
          "type" : "float"
        },
        "open" : {
          "type" : "float"
        },
        "stock_id" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        },
        "volume" : {
          "type" : "long"
        }
      }
    }
  }
}

看起來不錯,除了 stock_id 和 volume。

Data Type 要符合應用場景

現在我們來分析一下 stock_id (股票代號) 和 volume (成交股數) 這兩個欄位的 Data Type 應該如何設計。

stock_id (股票代號)

ES 為 stock_id 設定的 data type 為 "text",在查詢的時候會以全文檢索的方式進行,只要文字符合,就會被查出來,這顯然需要小擔心一下;此外, ES 還為 stock_id 設定了multi-fields,根據官方文件, 可以用來做 sorting 和 aggregations,這個需求對搜尋股票代號來說,也挺多餘的。

股票代號有獨一無二的特性,所以最適合的 Data Type ,我認為應該是 " keyword ",它的特性是在搜尋時會 "exact matching"。keyword field 是由 keyword anayler 分析,keyword anayler 其實就是一種 no-op (不做任何事) 的 analyer。有關 analyer ,我找一天再來深入研究。

volume (成交股數)

ES 設定的 data type 的 long。來看看 long 和 integer 的數值範圍:

  • long : -2^63 ~ 2^63
  • integer: -2^31 ~ 2^31

其中 integer 的最大正整數為 2,147,483,647,換算成張數大約為 200萬張。如果是日成交量,單日成效量能超過百萬張已屬難見,到 2 百萬張應該是此生難見,所以我認為用 integer type 足矣。這樣能有效的節省儲存空間。

但如果要做週/月的統計,超過 integer 範圍就比較容易達成,我的設計會把週/月的統計,放在另一個 Index,並且 volume 欄位設計成 long。

建立 Mapping

透過下面的 API 可以在建立新的 Index 的同時,建立 Mapping。

PUT /history-prices-daily
{
  "mappings": {
    "properties": {
      "close" : {
        "type" : "float"
      },
      "date" : {
        "type" : "date"
      },
      "high" : {
        "type" : "float"
      },
      "low" : {
        "type" : "float"
      },
      "open" : {
        "type" : "float"
      },
      "stock_id" : {
        "type" : "keyword"
      },
      "volume" : {
        "type" : "integer"
      }
    }
  }
}

酷! 這下資料格式的問題搞定了。下一步,繼續研究如何上傳大量資料!


上一篇
[Day05] 盤後資料上 ES Cloud - 以 Postman 為例
下一篇
[Day07] 一次上傳多筆資料 - Bulk API
系列文
Elastic 戰台股30

尚未有邦友留言

立即登入留言