摘要:則在讀取數(shù)據(jù)時(shí)將兩個(gè)中文字段混淆成了一個(gè)字段,導(dǎo)致整個(gè)數(shù)據(jù)結(jié)構(gòu)錯(cuò)亂。三條路子全軍覆沒,這讓我情何以堪,好在使用的經(jīng)驗(yàn)頗豐,通過中文的轉(zhuǎn)換和切割就輕松解決了這個(gè)問題。
概述
在現(xiàn)實(shí)場景中,由于數(shù)據(jù)來源的異構(gòu),數(shù)據(jù)源的格式往往是難以統(tǒng)一的,這就導(dǎo)致大量具有價(jià)值的數(shù)據(jù)通常是以非結(jié)構(gòu)化的形式聚合在一起的。對于這些非結(jié)構(gòu)化數(shù)據(jù),最常見的數(shù)據(jù)結(jié)構(gòu)就是JSON,而對應(yīng)的數(shù)據(jù)庫就是MongoDB。
利用MongoDB這樣的NoSQL數(shù)據(jù)庫,我們可以把異構(gòu)的數(shù)據(jù)源整合到若干個(gè)collection中,通過key-value的形式對數(shù)據(jù)進(jìn)行增刪改查。雖然MongoDB在數(shù)據(jù)聚合上有天然的優(yōu)勢,但是在事務(wù)處理(OLTP)與數(shù)據(jù)分析(OLAP)上的表現(xiàn)卻不盡人意。由于MongoDB自身是一個(gè)文檔型數(shù)據(jù)庫,一方面,MongoDB 并沒有事務(wù)的概念,所以在需要保證數(shù)據(jù)一致性的場景下并不好用。另一方面,MongoDB的join查詢也沒有RDBMS來得直觀方便,所以在需要多表關(guān)聯(lián)查詢的場景下也非常捉急。
通常,對于小數(shù)據(jù)集,我們都會將數(shù)據(jù)導(dǎo)入到類似MySQL這樣的RDBMS中做進(jìn)一步的結(jié)構(gòu)化處理,對于大數(shù)據(jù)集則可以通過Hive導(dǎo)入到HDFS上。那么,將MongoDB的非結(jié)構(gòu)化數(shù)據(jù)導(dǎo)入到RDBMS中的最優(yōu)方案又是什么呢?本文將對非結(jié)構(gòu)化數(shù)據(jù)與結(jié)構(gòu)化數(shù)據(jù)的管道構(gòu)建做詳細(xì)的討論。
從 Mongo 到 MySQL iPython從Mongo遷移數(shù)據(jù)到MySQL,我的第一個(gè)反應(yīng)是應(yīng)該寫個(gè)腳本,我首先想到了用Python從Mongo讀取數(shù)據(jù)到內(nèi)存中然后再批量寫入MySQL。
這里,我選擇了使用pymongo。
%% bash pip install pymongo # 這里不需要安裝 Mongo的client
首先是讀取Mongo數(shù)據(jù)
from pymongo import MongoClient client = MongoClient("192.168.1.100", 27017) db = client["tesedb"] posts = db.test_collection condition = {"_id":"harryzhu"} result_set = posts.find(condition) for i in result_set: print(i)
這里由于python會有中文的問題,我自己定義了一個(gè)將unicode轉(zhuǎn)為utf-8的函數(shù):
def getMongoData(data,field): if data[field] is None: return("") else: if isinstance(data[field], unicode): return(data[field].encode("utf-8")) else: return(data[field])
接著,準(zhǔn)備往MySQL中導(dǎo)入數(shù)據(jù)
%% bash pip install MySQL-python # 這里需要安裝 MySQL的client
import MySQLdb db = MySQLdb.connect("192.168.1.100","root","harryzhu","testdb" ) cursor = db.cursor() values = r"("{id}","{value}","{datetime}","{stock_code}","{share}")".format(id=getMongoData(i,"_id"),value=getMongoData(i,"value"),datetime=getMongoData(i,"datetime"),stock_code=getMongoData(i,"stock_code"),share=getMongoData(i,"share")) sql = r"INSERT INTO `FinanceR` (`id`,`value`,`datetime`,`stock_code`,`share`) VALUES " + values try: cursor.execute(sql) db.commit() except: db.rollback() db.close()
從Mongo中讀取的JSON需要在這里拼接SQL語句是一件用戶體驗(yàn)非常糟糕的事情,如果有更好的方法歡迎在留言區(qū)討論。在嘗試拼接sql 2個(gè)小時(shí)后,我果斷放棄了用Python導(dǎo)數(shù)據(jù)的想法。
R由于拼接SQL是非常蛋疼的一件事情,我想到了利用R中的data frame直接完成數(shù)據(jù)的插入黑魔法。
首先,同樣是需要將數(shù)據(jù)從Mongo中讀取出來.在嘗試使用RMongo,rmongodb以及mongolite之后,我依然選擇了比較古老的RMongo。在使用的過程中,這三個(gè)包都有各自的問題。
rmongodb的教程含糊不清,看了很久都沒有找到調(diào)用遠(yuǎn)程mongo數(shù)據(jù)庫的case,而出于jeroenooms大人之手的后起之秀mongolite則在導(dǎo)入數(shù)據(jù)的時(shí)候果斷的丟失了非常關(guān)鍵的_id字段,在安裝最新包之后會出現(xiàn)jsonlite依賴包的異常。RMongo則在讀取數(shù)據(jù)時(shí)將兩個(gè)中文字段混淆成了一個(gè)字段,導(dǎo)致整個(gè)數(shù)據(jù)結(jié)構(gòu)錯(cuò)亂。
三條路子全軍覆沒,這讓我情何以堪,好在使用R的經(jīng)驗(yàn)頗豐,通過中文的轉(zhuǎn)換和切割就輕松解決了這個(gè)問題。
下面演示一下如何使用RMongo解決Mongo數(shù)據(jù)的讀?。?/p>
install.packages("RMongo")
Sys.setenv("JAVA_HOME"="/usr/bin/java") library(RMongo) # 這里不需要安裝 Mongo的client library(dplyr) # 設(shè)置數(shù)據(jù)庫 FinanceR <- RMongo::mongoDbConnect(host="192.168.1.100") dbShowCollections(FinanceR) # 設(shè)置查詢語句 condition = "{}" # 得到返回結(jié)果 output <- RMongo::dbGetQuery(FinanceR, collection="portfolio_20160619", condition, skip=0, limit=2) input <- output %>% dplyr::mutate(stock_name1 = iconv(strsplit(iconv(stock_name,from = "utf-8", to = "gbk"),"100")[[1]][1],from = "gbk",to = "utf-8"))%>% dplyr::mutate(portfolio_name = iconv(strsplit(iconv(stock_name,from = "utf-8", to = "gbk"),"100")[[1]][2],from = "gbk",to = "utf-8"))%>% dplyr::select(-stock_name)%>% rbind(cum_value="",risk="") dbDisconnect(FinanceR)
現(xiàn)在,我們已經(jīng)把Mongo中的數(shù)據(jù)成功導(dǎo)入到了內(nèi)存中,下面將講解如何使用黑魔法直接將整個(gè)data frame壓入數(shù)據(jù)庫。
install.packages("RMySQL")
library(RMySQL) # 這里不需要安裝 MySQL的client con <- RMySQL::dbConnect(RMySQL::MySQL(), user="FinanceR", password="FinanceR", dbname="FinanceR", host="192.168.1.100") # 選擇追加,而不是重寫的方式來添加數(shù)據(jù),否則數(shù)據(jù)庫的schema會被重寫 RMySQL::dbWriteTable(con,input,row.names = FASLE, overwrite = FALSE, append = TRUE) on.exit(dbDisconnect(con))Shell
Python 和 R 的方式各有利弊,對于Python而言目前簡單粗暴的方式就是SQL拼接,而R則在流水化上比較困難。所以最后轉(zhuǎn)向?qū)で骃hell命令的方式,通過調(diào)用 Mongo client 和 MySQL client 的 API 來完成整個(gè)數(shù)據(jù)的轉(zhuǎn)化操作。
經(jīng)過研究發(fā)現(xiàn) Mongo Client 提供了將數(shù)據(jù)轉(zhuǎn)成 csv 格式的接口,之后mysql則通過load命令可以將數(shù)據(jù)加載到數(shù)據(jù)庫中。
結(jié)論通過將非結(jié)構(gòu)化數(shù)據(jù)轉(zhuǎn)化為 data frame 后直接壓入 RDBMS,一方面省去了枯燥的SQL拼接,一方面操作又直觀清晰不易出錯(cuò),對于小數(shù)據(jù)集合,直接用這樣的方法增量導(dǎo)入數(shù)據(jù)不失為一種好方法,對于批量數(shù)據(jù)的流水化則采用Shell腳本調(diào)用Mongo和MySQL客戶端命令較為合適。
參考資料Python MySQL Database Access
R client to interface with MongoDB
python+mongoDB+pymongo常見命令及簡單案例
更優(yōu)閱讀體驗(yàn)可直接訪問原文地址:https://segmentfault.com/a/1190000005750424
作為分享主義者(sharism),本人所有互聯(lián)網(wǎng)發(fā)布的圖文均遵從CC版權(quán),轉(zhuǎn)載請保留作者信息并注明作者 Harry Zhu 的 FinanceR專欄:https://segmentfault.com/blog/harryprince,如果涉及源代碼請注明GitHub地址:https://github.com/harryprince。微信號: harryzhustudio
商業(yè)使用請聯(lián)系作者。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/38018.html
摘要:概述在真實(shí)的數(shù)據(jù)科學(xué)世界里,我們會有兩個(gè)極端,一個(gè)是業(yè)務(wù),一個(gè)是工程。偏向業(yè)務(wù)的數(shù)據(jù)科學(xué)被稱為數(shù)據(jù)分析,也就是型數(shù)據(jù)科學(xué)。所以說,同時(shí)學(xué)會和這兩把刷子才是數(shù)據(jù)科學(xué)的王道。 showImg(https://segmentfault.com/img/bVAgki?w=980&h=596); 概述 在真實(shí)的數(shù)據(jù)科學(xué)世界里,我們會有兩個(gè)極端,一個(gè)是業(yè)務(wù),一個(gè)是工程。偏向業(yè)務(wù)的數(shù)據(jù)科學(xué)被稱為數(shù)據(jù)...
摘要:對于異常機(jī)制的合理運(yùn)用是直接關(guān)系到碼農(nóng)飯碗的事情所以,本文將具體介紹一下和的異常處理機(jī)制,闡明二者在異常處理機(jī)制上的異同。下面將具體介紹二者的異常處理機(jī)制。 概述 showImg(https://segmentfault.com/img/remote/1460000006760426); 異常處理,是編程語言或計(jì)算機(jī)硬件里的一種機(jī)制,用于處理軟件或信息系統(tǒng)中出現(xiàn)的異常狀況(即超出程序正...
摘要:概述工欲善其事必先利其器,如果現(xiàn)在要評選數(shù)據(jù)科學(xué)中最好用的編輯器注意一定是可以通過訪問的,和一定是角逐的最大熱門,正確使用編輯器可以很大地提升我們的工作效率。 概述 showImg(https://segmentfault.com/img/bVAdol); 工欲善其事必先利其器,如果現(xiàn)在要評選數(shù)據(jù)科學(xué)中最好用的Web 編輯器(注意一定是可以通過Web訪問的),RStudio和Jupyt...
摘要:另外一個(gè)我們同時(shí)使用兩種語言的原因是已有的統(tǒng)計(jì)學(xué)工具與包。對另一些為讀者寫數(shù)據(jù)科學(xué)工具的人來說他們從一開始就考慮了這些跨語言。和實(shí)際上是用實(shí)現(xiàn)的這是條阻力最小的路徑。無論是哪個(gè)贏得這場語言戰(zhàn)爭,和都將保持在數(shù)據(jù)科學(xué)屆的地位。 showImg(https://segmentfault.com/img/remote/1460000006762469); 概述 幾周前,我有幸在 Scipy ...
摘要:然而,它最終變成了一種昂貴的選擇,并不總是具有最新的統(tǒng)計(jì)功能。對于大多數(shù)專業(yè)人士而言,這是昂貴的且沒有能力以個(gè)人身份購買。 showImg(https://segmentfault.com/img/remote/1460000019466629); 介紹 我們熱衷于比較! 從智能手機(jī)中的三星,蘋果和HTC,移動操作系統(tǒng)中的iOS,Android和Windows,到即將進(jìn)行選舉的候選人的...
閱讀 1175·2021-11-16 11:45
閱讀 1042·2021-09-04 16:41
閱讀 3088·2019-08-29 16:40
閱讀 2865·2019-08-29 15:34
閱讀 2681·2019-08-29 13:11
閱讀 1743·2019-08-29 12:58
閱讀 1735·2019-08-28 18:00
閱讀 1785·2019-08-26 18:26