【01】把 Elasticsearch 當資料庫使:表結構定義

TaoWen發表於2016-02-14

Elaticsearch 有非常好的查詢效能,以及非常強大的查詢語法。在一定場合下可以替代RDBMS做為OLAP的用途。但是其官方查詢語法並不是SQL,而是一種Elasticsearch獨創的DSL。主要是兩個方面的DSL:

這兩個DSL說實話是不好學習和理解的,而且即便掌握了寫起來也是比較繁瑣的,但是功能卻非常強大。本系列文章是為了兩個目的:

  • 通過類比SQL的概念,實驗並學習Elasticsearch聚合DSL的語法和語義
  • 用 python 實現一個翻譯器,能夠使用 SQL 來完成 Elasticsearch 聚合DSL一樣的功能。這個小指令碼可以在日常工作中做為一件方便的利器

基礎Elasticsearch知識(比如什麼是文件,什麼是索引)這裡就不贅述了。我們的重點是學習其查詢和聚合的語法。在本章中,我們先來準備好樣本資料。選擇的樣本資料是全美的股票列表(http://www.nasdaq.com/screeni…)。選擇這份資料的原因是因為其維度比較豐富(ipo年份,版塊,交易所等),而且有數字欄位用於聚合(最近報價,總市值)。資料下載為csv格式(https://github.com/taowen/es-…),並且有一個匯入指令碼(https://github.com/taowen/es-…

下面是匯入Elasticsearch的mapping(相當於關係型資料庫的表結構定義):

{
    "symbol": {
        "properties": {
            "sector": {
                "index": "not_analyzed", 
                "type": "string"
            }, 
            "market_cap": {
                "index": "not_analyzed", 
                "type": "long"
            }, 
            "name": {
                "index": "analyzed", 
                "type": "string"
            }, 
            "ipo_year": {
                "index": "not_analyzed", 
                "type": "integer"
            }, 
            "exchange": {
                "index": "not_analyzed", 
                "type": "string"
            }, 
            "symbol": {
                "index": "not_analyzed", 
                "type": "string"
            }, 
            "last_sale": {
                "index": "not_analyzed", 
                "type": "long"
            }, 
            "industry": {
                "index": "not_analyzed", 
                "type": "string"
            }
        }, 
        "_source": {
            "enabled": true
        }, 
        "_all": {
            "enabled": false
        }
    }
}

對於把 Elasticsearch 當作資料庫來使用,預設以下幾個設定

  • 把所有欄位設定為 not_analyzed
  • _source 開啟,這樣就不用零散地儲存每個欄位了,大部分情況下這樣更高效
  • _all 關閉,因為檢索都是基於 k=v 這樣欄位已知的查詢的

執行python import-symbol.py匯入完成資料之後,執行

GET http://127.0.0.1:9200/symbol/_count

返回

{"count":6714,"_shards":{"total":3,"successful":3,"failed":0}}

可以看到文件已經被匯入索引了。除了匯入一個股票的列表,我們還可以把歷史的股價給匯入到資料庫中。這個資料比較大,放在了網盤上下載(https://yunpan.cn/cxRN6gLX7f9md 訪問密碼 571c)(http://pan.baidu.com/s/1nufbLMx 訪問密碼 bes2)。執行python import-quote.py 匯入

 "quote": {
    "_all": {
      "enabled": false
    },
    "_source": {
      "enabled": true
    }, 
    "properties": {
      "date": {
        "format": "strict_date_optional_time||epoch_millis",
        "type": "date"
      },
      "volume": {
        "type": "long"
      },
      "symbol": {
        "index": "not_analyzed",
        "type": "string"
      },
      "high": {
        "type": "long"
      },
      "low": {
        "type": "long"
      },
      "adj_close": {
        "type": "long"
      },
      "close": {
        "type": "long"
      },
      "open": {
        "type": "long"
      }
    }
  }

從 mapping 的角度,和表結構定義是非常類似的。除了_source,_all和analyzed這幾個概念,基本上沒有什麼差異。Elasticsearch做為資料庫最大的區別是 index/mapping 的關係,以及 index 通配這些。

相關文章