1. 程式人生 > >億萬資料量級mongoDB中高效查詢同一欄位的所有不同值集合

億萬資料量級mongoDB中高效查詢同一欄位的所有不同值集合

   公司線上資料用的是mongodb儲存(其實線下一般也用mongodb),最近負責一個專案,需要每天獲得線上資料庫中所有的賣家id和賣家店鋪名稱。其實簡單的將整個資料庫掃一遍,拿出需要的這兩個欄位,再過濾一遍就可以了,但總想試一試更高階點兒的方式,誰叫我懶呢,不想寫太多程式碼,不想做太多維護,還想快速準確拿資料。

    mongodb集合中doc(一個doc表示一個商品資訊)的資料格式如下圖所示,我要做是獲取所有的userId和nick欄位,然後去掉重複的即可。
這裡寫圖片描述

distinct指令

   distinct指令的詳細解釋及用法見官網。億萬級資料量的情況下,distinct指令看看就行了,不然等它執行的時間都夠睡一覺了。

mongoexport工具

   通過mongodb自帶的集合匯出工具mongoexport來實現。使用mongoexport匯出集合中需要的欄位到檔案中,然後對檔案進行排序和去重(先排序,後去重,因為uniq只會比較相鄰的兩行並去重)。

momgoexport -c author_name -c collection_name --csv --fields field1 fileld2 -o exported_data.csv
cat exported_data.csv | sort | uniq > unique.txt

需要注意的是:匯出的檔案過大的話,同樣會很耗時,甚至導致處理失敗。這個時候就需要將匯出的檔案進行分割成多個小檔案了。

split -d -b 10G exported_data.csv   # 將exported_data.csv分割成10G大小的多個小檔案,每個小檔案的結尾以數字結尾

切割好了檔案後,再對每個小檔案排序去重即可。

MapReduce

   mongodb中可以使用MapReduce很方便的進行分組統計,整個查詢統計過程不牽扯到過多的手工操作,程式碼量也少。

import pymongo
from bson.code import Code

client = pymongo.MongoClient('199.155.122.32:27018')
db = client['products'
] collection = db['products_20161107'] # map函式的作用是遍歷集合,呼叫emit函式將集合中userId、nick欄位以鍵值對的形式傳遞給reduce函式 mapper = Code(""" function(){ emit(this.userId, this.nick); } """) # reduce函式的作用對map函式傳遞過來的鍵值對進行處理, 每個<key, values>鍵值對中,key是userId欄位的值,values是具有相同userId的nick的陣列。由於我的程式中一個values的各個元素的值是相同的,所以沒有對values進行遍歷。 reducer = Code(""" function(key, values){ var result = {nick: values[0]}; return result; } """) # 啟動MapReduce, 將結果輸出到seller_info這個集合中 result = collection.map_reduce(mapper, reducer, 'seller_info') # 遍歷seller_info集合,檢視MapReduce結果 for doc in db['seller_info'].find(): print doc

我的程式的執行結果如下圖所示:
這裡寫圖片描述
從結果中我們可以看到,ruduce函式中key的值作為了_id欄位的值,返回結果result作為了values欄位的值。