麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 數據庫 > PostgreSQL > 正文

在PostgreSQL的基礎上創建一個MongoDB的副本的教程

2020-03-12 23:53:47
字體:
來源:轉載
供稿:網友

這篇文章主要介紹了在PostgreSQL的基礎上創建一個MongoDB的副本的教程,使在使用NoSQL的同時又能用到PostgreSQL中的東西,需要的朋友可以參考下

我有一個偷懶的想法。這個好點子該如何開始呢?好吧,這是一個恰如其分的小瘋狂:為什么不直接在Postgres的基礎上建立我們自己的MongoDB版本呢?這聽起來有點牽強附會,但卻簡單而實在。

當NoSQL運動風生水起的時候,Postgres社區沒有干坐著擺弄他們的大拇指。他們持續開發,貫穿整個Postgres的生態系統,幾個突出的功能吸引了我的眼球:整合JSON支持和PLV8。PLV8把V8 Javascript引擎引入到Postgres,他讓Javascript成為一個第一類別的語言(first-class language)。擁有JSON類型讓它能更容易地處理JSON(這很有效)。

開始前需要做的準備:

Postgres 9.2+ (as of this blog entry, 9.2 is in beta) - http://www.postgresql.org/ftp/source/

V8 - https://github.com/v8/v8

PLV8 - http://code.google.com/p/plv8js/wiki/PLV8

MongoDB的最低級別是集合. 集合可以用表來表示:

 

 
  1. CREATE TABLE some_collection ( 
  2. some_collection_id SERIAL NOT NULL PRIMARY KEY
  3. data JSON 
  4. ); 

字符型的JSON 被保存在 Postgres 表里,簡單易行 (現在看是這樣).

下面實現自動創建集合. 保存在集合表里:

 

 
  1. CREATE TABLE collection ( 
  2. collection_id SERIAL NOT NULL PRIMARY KEY
  3. name VARCHAR 
  4. ); 
  5.  
  6. -- make sure the name is unique 
  7. CREATE UNIQUE INDEX idx_collection_constraint ON collection (name); 

一旦表建好了,就可以通過存儲過程自動創建集合. 方法就是先建表,然后插入建表序列.

 

 
  1. CREATE OR REPLACE FUNCTION create_collection(collection varcharRETURNS 
  2. boolean AS $ 
  3. var plan1 = plv8.prepare('INSERT INTO collection (name) VALUES ($1)', [ 'varchar' ]); 
  4. var plan2 = plv8.prepare('CREATE TABLE col_' + collection + 
  5. ' (col_' + collection + '_id INT NOT NULL PRIMARY KEY, data JSON)'); 
  6. var plan3 = plv8.prepare('CREATE SEQUENCE seq_col_' + collection); 
  7.  
  8. var ret; 
  9.  
  10. try { 
  11. plv8.subtransaction(function () { 
  12. plan1.execute([ collection ]); 
  13. plan2.execute([ ]); 
  14. plan3.execute([ ]); 
  15.  
  16. ret = true
  17. }); 
  18. } catch (err) { 
  19. ret = false
  20.  
  21. plan1.free(); 
  22. plan2.free(); 
  23. plan3.free(); 
  24.  
  25. return ret; 
  26. $ LANGUAGE plv8 IMMUTABLE STRICT; 

有了存儲過程,就方便多了:

 

 
  1. SELECT create_collection('my_collection'); 

解決了集合存儲的問題,下面看看MongoDB數據解析. MongoDB 通過點式注解方法操作完成這一動作:

 

 
  1. CREATE OR REPLACE FUNCTION find_in_obj(data json, key varcharRETURNS 
  2. VARCHAR AS $ 
  3. var obj = JSON.parse(data); 
  4. var parts = key.split('.'); 
  5.  
  6. var part = parts.shift(); 
  7. while (part && (obj = obj[part]) !== undefined) { 
  8. part = parts.shift(); 
  9.  
  10. // this will either be the value, or undefined 
  11. return obj; 
  12. $ LANGUAGE plv8 STRICT; 

上述功能返回VARCHAR,并不適用所有情形,但對于字符串的比較很有用:

 

 
  1. SELECT data 
  2. FROM col_my_collection 
  3. WHERE find_in_obj(data, 'some.element') = 'something cool' 

除了字符串的比較, MongoDB還提供了數字類型的比較并提供關鍵字exists . 下面是find_in_obj() 方法的不同實現:

 

 
  1. CREATE OR REPLACE FUNCTION find_in_obj_int(data json, key varcharRETURNS 
  2. INT AS $ 
  3. var obj = JSON.parse(data); 
  4. var parts = key.split('.'); 
  5.  
  6. var part = parts.shift(); 
  7. while (part && (obj = obj[part]) !== undefined) { 
  8. part = parts.shift(); 
  9.  
  10. return Number(obj); 
  11. $ LANGUAGE plv8 STRICT; 
  12.  
  13. CREATE OR REPLACE FUNCTION find_in_obj_exists(data json, key varcharRETURNS 
  14. BOOLEAN AS $ 
  15. var obj = JSON.parse(data); 
  16. var parts = key.split('.'); 
  17.  
  18. var part = parts.shift(); 
  19. while (part && (obj = obj[part]) !== undefined) { 
  20. part = parts.shift(); 
  21.  
  22. return (obj === undefined ? 'f' : 't'); 
  23. $ LANGUAGE plv8 STRICT; 

接下來是數據查詢. 通過現有的材料來實現 find() 方法.

保存數據到集合中很簡單。首先,我們需要檢查JSON對象并尋找一個_id值。這部分代碼是原生的假設,如果_id已存在這意味著一個更新,否則就意味著一個插入。請注意,我們目前還沒有創建objectID,只使用了一個序列待其發生:

 

 
  1. CREATE OR REPLACE FUNCTION save(collection varchar, data json) RETURNS 
  2. BOOLEAN AS $ 
  3. var obj = JSON.parse(data); 
  4.  
  5. var id = obj._id; 
  6.  
  7. // if there is no id, naively assume an insert 
  8. if (id === undefined) { 
  9. // get the next value from the sequence for the ID 
  10. var seq = plv8.prepare("SELECT nextval('seq_col_" + 
  11. collection + "') AS id"); 
  12. var rows = seq.execute([ ]); 
  13.  
  14. id = rows[0].id; 
  15. obj._id = id; 
  16.  
  17. seq.free(); 
  18.  
  19. var insert = plv8.prepare("INSERT INTO col_" + collection + 
  20. " (col_" + collection + "_id, data) VALUES ($1, $2)"
  21. 'int''json']); 
  22.  
  23. insert.execute([ id, JSON.stringify(obj) ]); 
  24. insert.free(); 
  25. else { 
  26. var update = plv8.prepare("UPDATE col_" + collection + 
  27. " SET data = $1 WHERE col_" + collection + "_id = $2"
  28. 'json''int' ]); 
  29.  
  30. update.execute([ data, id ]); 
  31.  
  32. return true
  33. $ LANGUAGE plv8 IMMUTABLE STRICT; 

基于這個觀點,我們可以構建一些插入的簡單文檔:

 

 
  1. "name""Jane Doe"
  2. "address": { 
  3. "street""123 Fake Street"
  4. "city""Portland"
  5. "state""OR" 
  6. }, 
  7. "age": 33 
  8.  
  9. "name""Sarah Smith"
  10. "address": { 
  11. "street""456 Real Ave"
  12. "city""Seattle"
  13. "state""WA" 
  14.  
  15. "name""James Jones"
  16. "address": { 
  17. "street""789 Infinity Way"
  18. "city""Oakland"
  19. "state""CA" 
  20. }, 
  21. "age": 23 

讓我們創建一個集合并插入一些數據:

 

 
  1. work=# SELECT create_collection('data'); 
  2. create_collection 
  3. ------------------- 
  4. (1 row) 
  5.  
  6. work=# SELECT save('data''{ our object }'); 
  7. save 
  8. ------ 
  9. (1 row) 

你可以通過檢查“col_data”表的內容來查看對象。

其它翻譯版本(1)

現在我們已經有了一些數據,讓我們再查詢一下。假設我們想查找住在俄勒岡或華盛頓州年齡大于30的所有人,使用一個MongoDB風格的find():

 

 
  1. "$or": [ 
  2. "address.state""OR" 
  3. }, 
  4. "address.state""WA" 
  5. ], 
  6. "age": { 
  7. "$gt": 30 

因為上次我們已經創建了一些深度的包檢測,現在就很容易創建查詢并返回Jane Doe:

 

 
  1. SELECT data 
  2. FROM col_data 
  3. WHERE find_in_obj_int(data, 'age') > 30 
  4. AND ( 
  5. find_in_obj(data, 'address.state') = 'OR' 
  6. OR 
  7. find_in_obj(data, 'address.state') = 'WA' 

我采用了寫一個遞歸調用函數來建立WHERE子句的方法。它有點長,所以我沒有把它貼在這里而是放在GitHub上。一旦find()存儲過程被創建,我們就可以在查詢中使用它。我們應該能夠看到Jane Doe被返回:

 

 
  1. work=# SELECT find('data''{ "$or": [ { "address.state": "OR" }, { "address.state": "WA" } ], "age": { "$gt": 30 } }'); 

這樣奏效:它不優雅,但它奏效。這是一個概念的證明,而且幾乎沒有像它一樣好的可能。我之前曾被問過為什么不使用HSTORE。雖然你可以存儲嵌套的HSTORE和數組值,但它仍不是JSON,并且不容易通過PLV8操作。這將需要一個從HSTORE到JSON的序列器,這個序列器在任何時間將請求的返回序列化成MongoDB接受的數據形式,但依舊太容易在JavaScript中處理。這是次優選擇,畢竟我們是要在Postgres的基礎上創建一個MongoDB的副本。

源碼可以在GitHub上找到:fork并嘗試一下吧,記得回饋哦。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 久久久久久久久久一本门道91 | 天堂成人国产精品一区 | 色综合网在线观看 | 久久国产亚洲视频 | chinese 军人 gay xx 呻吟 | 国产va在线观看 | 天天夜天天操 | 92看片淫黄大片一级 | 九草在线视频 | 91麻豆精品国产91久久久无需广告 | 欧美精品一区二区三区四区 | 国产成人小视频在线观看 | 久久99精品久久久久久秒播放器 | 成人男女啪啪免费观看网站四虎 | 欧美成人精品一区二区 | 成人做爽爽爽爽免费国产软件 | 久久最新网址 | 免费一级在线观看 | 精品xxxx户外露出视频 | 成人爽a毛片免费啪啪红桃视频 | 久久久在线免费观看 | 中文字幕偷拍 | 免费看污视频在线观看 | 激情在线视频 | 91成人久久 | 一级电影免费 | 色啪综合 | 亚洲尻逼视频 | 黄网站色成年大片免费高 | 日韩av电影在线免费观看 | 成人在线视频免费播放 | 国产精品久久久久久久亚洲按摩 | 永久在线观看电影 | 狠狠干天天操 | 日日鲁一鲁视频 | 特大黑人videos与另类娇小 | av在线播放地址 | 欧美囗交 | 国产精品9191 | 国产亚洲精品综合一区91 | 亚洲二区三区在线 |