MongoDB 資料庫是現在知名的 NoSQL 資料庫,他讓程式開發部門「避開」與資料庫管理人員申請資料欄位的往返溝通,直接塞想要的資料存起來。聽說這在作為網頁後端資料庫很方便。
要是想要把這裡面的資料拉出來分析,就稍微不方便一些,因為他的資料都塞在一份份的 JSON 檔案裡面,要單獨取出大量某個「欄位」(JSON Key)的資料作運算,分析,就有點不方便,尤其要進行普通的關聯式資料庫的 JOIN,尤其不容易。
PostgreSQL 提供的 Foreign Data Wrapper 中,有跨接 MongoDB 的套件,叫做 mongo_fdw,是一個由 EnterpriseDB 公司維護的開源專案。這個模組能夠對 MongoDB 的 JSON 資料,取過來 PostgreSQL 裡面,當成一般表格處理,便能夠和現有資料庫的資料,進行進一步的分析。
環境:
CentOS 7.2
EnterpriseDB 企業版 EPAS 9.5
|
CentOS 6.8
MongoDB 3.4 版
|
如果是一般 PostgreSQL,基本上編譯過程是一樣的,在此就根據企業版進行。
mongo_fdw 專案位置 https://github.com/EnterpriseDB/mongo_fdw
該套件要自行編譯,所以要先了解套件的相依性,才能進行編譯
套件相依性:
v 1.5.0
| |
v 1.5.0
| |
openssl-devel
|
使用 YUM 安裝即可
|
以上相依套件都會由 mongo_fdw 進行編譯,無須額外先行取得、編譯
先設置環境
edb=# create user conn_mongo; CREATE ROLE edb=# create database conn_mongo owner conn_mongo; CREATE DATABASE
編譯套件前,先安裝編譯工具
[root@edbVM ~]# yum group install "Development Tools" [root@edbVM ~]# yum install openssl-devel
下載套件
[root@edbVM ~]# wget https://github.com/EnterpriseDB/mongo_fdw/archive/master.zip -O mongo_fdw-master.zip [root@edbVM ~]# unzip mongo_fdw-master.zip [root@edbVM ~]# cd mongo_fdw-master
截至 2016/12/08 為止,要對企業版9.5成功編譯,需修改編譯選項
[root@edbVM ~]# vi autogen.sh . . . function install_json_lib { cd json-c sh ./autogen.sh ./configure --enable-shared --with-pic make install cd .. } . . . function install_mongoc_driver { cd mongo-c-driver ./configure --enable-ssl=yes --with-libbson=auto make install cd .. }
編譯套件:請以 root 進行
[root@edbVM mongo_fdw-master]# ./autogen.sh --with-master [root@edbVM mongo_fdw-master]# echo '/usr/local/lib/' >> /etc/ld.so.conf [root@edbVM mongo_fdw-master]# ldconfig [root@edbVM mongo_fdw-master]# source /opt/PostgresPlus/9.5AS/pgplus_env.sh [root@edbVM mongo_fdw-master]# PKG_CONFIG_PATH=/usr/local/lib/pkgconfig/ make Makefile.meta install
接著便能登入資料庫進行設置
首先以 Super User 登入,啟用 mongo_fdw
conn_mongo=# CREATE EXTENSION mongo_fdw; CREATE EXTENSION conn_mongo=# GRANT ALL ON FOREIGN DATA WRAPPER mongo_fdw to conn_mongo; GRANT
接著登入前面設定的 Postgres 帳戶作設定:MongoDB 一端的登入,mongo_fdw 使用帳號密碼登入 MongoDB 資料庫,所以在 MongoDB 上,就要注意相關的存取權限有沒有設置完成。
conn_mongo=# \c conn_mongo conn_mongo
conn_mongo=> CREATE SERVER mongo_server
FOREIGN DATA WRAPPER mongo_fdw
OPTIONS (address '1**.1**.9*.1**', port '27021');
conn_mongo=> CREATE USER MAPPING FOR conn_mongo
SERVER mongo_server
OPTIONS (username 'bbb', password 'bbb');
conn_mongo=> -- 建立外部表
conn_mongo=> CREATE FOREIGN TABLE testmongo(
_id NAME,
testfield text)
SERVER mongo_server
OPTIONS (database 'test', collection 'testc');
在此,要登入的「邏輯」資料庫為 test,而存取的 MongoDB 資料為 testc,以下提供在 mongo shell 下顯示的資料資訊
[mongo@mongovm ~]$ mongo localhost:27021 MongoDB shell version v3.4.0 connecting to: mongodb://localhost:27021 MongoDB server version: 3.4.0 Server has startup warnings: 2016-12-08T02:27:11.624+0000 I STORAGE [initandlisten] 2016-12-08T02:27:12.259+0000 I CONTROL [initandlisten] 2016-12-08T02:27:12.259+0000 I CONTROL [initandlisten] ** WARNING: Access control is not enabled for the database. 2016-12-08T02:27:12.259+0000 I CONTROL [initandlisten] ** Read and write access to data and configuration is unrestricted. 2016-12-08T02:27:12.259+0000 I CONTROL [initandlisten] ** WARNING: You are running this process as the root user, which is not recommended. 2016-12-08T02:27:12.259+0000 I CONTROL [initandlisten] 2016-12-08T02:27:12.260+0000 I CONTROL [initandlisten] 2016-12-08T02:27:12.260+0000 I CONTROL [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/enabled is 'always'. 2016-12-08T02:27:12.260+0000 I CONTROL [initandlisten] ** We suggest setting it to 'never' 2016-12-08T02:27:12.260+0000 I CONTROL [initandlisten] 2016-12-08T02:27:12.260+0000 I CONTROL [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/defrag is 'always'. 2016-12-08T02:27:12.260+0000 I CONTROL [initandlisten] ** We suggest setting it to 'never' 2016-12-08T02:27:12.260+0000 I CONTROL [initandlisten] > db.stats() { "db" : "test", "collections" : 1, "views" : 0, "objects" : 1, "avgObjSize" : 42, "dataSize" : 42, "storageSize" : 16384, "numExtents" : 0, "indexes" : 1, "indexSize" : 16384, "ok" : 1 } > show collections testc > db.testc.find().pretty() { "_id" : ObjectId("5848c5513f86435374c3ab0a"), "testfield" : "test" } >
以上顯示了一筆測試資料,接著我們從 PostgreSQL 撈這筆資料來:
conn_mongo=> select * from testmongo; _id | testfield --------------------------+----------- 5848c5513f86435374c3ab0a | test (1 row)
如此可以發現,mongo_fdw 的功能是將 MongoDB 下的 JSON Document 當中的 Key 對應成 PostgreSQL 資料庫欄位,內容成為一筆資料。
接著試著插入一筆資料
conn_mongo=> insert into testmongo(testfield) values('hi'); INSERT 0 1 conn_mongo=> select * from testmongo; _id | testfield --------------------------+----------- 5848c5513f86435374c3ab0a | test 58490d53661f354f7f2975a7 | hi (2 rows)
除了如上面轉換成表格資料以外,mongo_fdw 還支援把整個 JSON 以 PostgreSQL 的 JSON 欄位來裝資料。不過要注意的是,這個欄位名稱「限定」叫做 __doc,JSON 型態(JSONB 不可以);還有,這功能的目標指用來「擷取」資料,不包含用這個欄位寫資料進去 MongoDB:
conn_mongo=> CREATE FOREIGN TABLE test2mongo(__doc json) SERVER mongo_server OPTIONS (database 'test', collection 'testc2'); CREATE FOREIGN TABLE conn_mongo=> select * from test2mongo; __doc ------------------------------------------------------------------------------------- { "_id" : { "$oid" : "5850b7888dad99b6c35390d6" }, "i" : 0, "datafrom" : "test" } { "_id" : { "$oid" : "5850b7888dad99b6c35390d7" }, "i" : 1, "datafrom" : "test" } { "_id" : { "$oid" : "5850b7888dad99b6c35390d8" }, "i" : 2, "datafrom" : "test" } (3 rows)
筆記就紀錄到這裡~
如此,有了 mongo_fdw,PostgreSQL 便具備了與 NoSQL 資料庫溝通的更好能力~
最後,感謝同事 Brian 和 EnterpriseDB 客服團隊(Customer Portal Support Team)的大力協助~才能完成這份筆記。
參考資料:
Clarence's Wicked Mind: Playing with PostgreSQL FDW for MongoDB
A tour of Postgres' Foreign Data Wrappers Craig Kerstiens
A tour of Postgres' Foreign Data Wrappers Craig Kerstiens
- 其他參考
MongoDB 採用 mongo_fdw 專案作修改,提供了他自己的「SQL 指令」界面的支援,稱作 MongoDB BI Connector
不過在 BI COnnector 2.0 版,便傾向去模仿 MySQL ~
簡單安裝 MongoDB
How To Install MongoDB on CentOS 7 | DigitalOcean
沒有留言:
張貼留言