先聲明使用 mongodb 作為資料存放的方式, 只是筆者目前的階段性選擇, 在未來何時會因應需求而跳槽也未可知, 但這裡還是會說明選擇以此作為資料存放的理由。
在最初的想法是打算以 JSON 格式的文本直接存放資料, 但文件與資料庫還是有許多差異 database vs flat files, 為了讓蒐集下來的資料可以保有查詢的功能, 後續就採用 mongodb 來存放。
- 運行容易
- Schema-free 的模型在資料建置上自由
- 資料容易與 JSON 或是 python 的 dict 資料結構對應其關係, 易理解
Server Side
筆者在 Mac 安裝的方式, 相信 UNIX-like 的環境都不會太困難 : )
brew install mongodb
接下來就是讓 server 跑起來, 最後一個參數指定本地端作為 database 建置的路徑
mongod --config /usr/local/etc/mongod.conf --dbpath <local db path>
在 server 跑起來後, 我們就可以透過 mongo shell 在 shell 中執行 client 端的操作, 筆者用來檢查資料庫當前的狀態滿方便的。
- show dbs : 顯示當前的 database
- use dbname : 切換目前的 database 至 dbname
- show collections : 顯示當前 database 中的 collection 名稱 (collection 由 document 集結而成, document 為 mongodb 的儲存單元)
- db.colname.count() : 顯示名為 colname 的 collection 中 document 數量
- db.colname.findOne({Key:Value})
Client Side
為了整合進 Scrapy 的 pipeline, 要先來安裝 python 的 mongodb client 模組 pymongo
pip install pymongo
Demo Code, API reference
from pymongo import MongoClient
item = {'name':'test'}
client = MongoClient()
db = client['Demo']
db.demo.insert_one(item)
範例程式很簡單的示範了
- 連接 mongodb server
- 新增一個名為 Demo 的資料庫
- 將一筆資料寫入 Demo 資料庫中的 demo collection 中
Aggregation Pipeline
要對 database 中的資料群進行處理, 除了早期提供的 Map Reduce, 目前的版本也已經另外支援 Aggregation Pipeline 的方法, 在效能的比較上可以參考 Aggregate vs Map-Reduce
使用方式是透過 mongodb 提供的 operator 去描述資料流在 pipeline 中的每個 stage 要如何去彙整, 並一層一層的往下一個 stage 傳遞。
(from Official Document aggregation pipeline, example)
以上就是如何存儲 mongodb、並整理資料的方式, 當然在 python 中可以用更貼近習慣的方式, 寫程式碼去整理 (效能當然比內建的方式差多了), 但要熟悉這套描述運算的方式也是需要一些時間, 有些客製化的需求也未必能滿足需求, 方法可以自行取捨看看。