国产激情自拍_国产9色视频_丁香花在线电影小说观看 _久久久久国产精品嫩草影院

首頁 > 數據庫 > PostgreSQL > 正文

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

2020-10-29 21:49:53
字體:
來源:轉載
供稿:網友

我有一個偷懶的想法。這個好點子該如何開始呢?好吧,這是一個恰如其分的小瘋狂:為什么不直接在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的最低級別是集合.  集合可以用表來表示:
 

  CREATE TABLE some_collection (   some_collection_id SERIAL NOT NULL PRIMARY KEY,   data JSON  );

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

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

  CREATE TABLE collection (   collection_id SERIAL NOT NULL PRIMARY KEY,   name VARCHAR  );   -- make sure the name is unique  CREATE UNIQUE INDEX idx_collection_constraint ON collection (name);

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

 CREATE OR REPLACE FUNCTION create_collection(collection varchar) RETURNS  boolean AS $$   var plan1 = plv8.prepare('INSERT INTO collection (name) VALUES ($1)', [ 'varchar' ]);   var plan2 = plv8.prepare('CREATE TABLE col_' + collection +    ' (col_' + collection + '_id INT NOT NULL PRIMARY KEY, data JSON)');   var plan3 = plv8.prepare('CREATE SEQUENCE seq_col_' + collection);      var ret;      try {    plv8.subtransaction(function () {     plan1.execute([ collection ]);     plan2.execute([ ]);     plan3.execute([ ]);         ret = true;    });   } catch (err) {    ret = false;   }      plan1.free();   plan2.free();   plan3.free();      return ret;  $$ LANGUAGE plv8 IMMUTABLE STRICT;

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

 SELECT create_collection('my_collection');


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

  CREATE OR REPLACE FUNCTION find_in_obj(data json, key varchar) RETURNS  VARCHAR AS $$   var obj = JSON.parse(data);   var parts = key.split('.');      var part = parts.shift();   while (part && (obj = obj[part]) !== undefined) {    part = parts.shift();   }      // this will either be the value, or undefined   return obj;  $$ LANGUAGE plv8 STRICT;

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

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

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

  CREATE OR REPLACE FUNCTION find_in_obj_int(data json, key varchar) RETURNS  INT AS $$   var obj = JSON.parse(data);   var parts = key.split('.');      var part = parts.shift();   while (part && (obj = obj[part]) !== undefined) {    part = parts.shift();   }      return Number(obj);  $$ LANGUAGE plv8 STRICT;     CREATE OR REPLACE FUNCTION find_in_obj_exists(data json, key varchar) RETURNS  BOOLEAN AS $$   var obj = JSON.parse(data);   var parts = key.split('.');      var part = parts.shift();   while (part && (obj = obj[part]) !== undefined) {    part = parts.shift();   }      return (obj === undefined ? 'f' : 't');  $$ LANGUAGE plv8 STRICT;

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

  CREATE OR REPLACE FUNCTION save(collection varchar, data json) RETURNS  BOOLEAN AS $$   var obj = JSON.parse(data);    var id = obj._id;    // if there is no id, naively assume an insert   if (id === undefined) {    // get the next value from the sequence for the ID    var seq = plv8.prepare("SELECT nextval('seq_col_" +      collection + "') AS id");    var rows = seq.execute([ ]);        id = rows[0].id;    obj._id = id;     seq.free();       var insert = plv8.prepare("INSERT INTO col_" + collection +      " (col_" + collection + "_id, data) VALUES ($1, $2)",      [ 'int', 'json']);     insert.execute([ id, JSON.stringify(obj) ]);    insert.free();   } else {    var update = plv8.prepare("UPDATE col_" + collection +     " SET data = $1 WHERE col_" + collection + "_id = $2",     [ 'json', 'int' ]);     update.execute([ data, id ]);   }    return true;  $$ LANGUAGE plv8 IMMUTABLE STRICT;

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

  {   "name": "Jane Doe",   "address": {    "street": "123 Fake Street",    "city": "Portland",    "state": "OR"   },   "age": 33  }     {   "name": "Sarah Smith",   "address": {    "street": "456 Real Ave",    "city": "Seattle",    "state": "WA"   }  }     {   "name": "James Jones",   "address": {    "street": "789 Infinity Way",    "city": "Oakland",    "state": "CA"   },   "age": 23  }

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

 

  work=# SELECT create_collection('data');   create_collection  -------------------   t  (1 row)     work=# SELECT save('data', '{ our object }');   save  ------   t  (1 row)

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

其它翻譯版本(1)

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

  {   "$or": [    {     "address.state": "OR"    },    {     "address.state": "WA"    }   ],   "age": {    "$gt": 30   }  }

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

  SELECT data   FROM col_data   WHERE find_in_obj_int(data, 'age') > 30    AND (       find_in_obj(data, 'address.state') = 'OR'      OR       find_in_obj(data, 'address.state') = 'WA'      )

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

  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并嘗試一下吧,記得回饋哦。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
国产激情自拍_国产9色视频_丁香花在线电影小说观看 _久久久久国产精品嫩草影院
国产香蕉在线| 国产粉嫩一区二区三区在线观看| 黄色在线视频观看网站| 国产一二区在线观看| 亚洲夜夜综合| 99在线免费视频| 国产黄视频在线观看| 国产精品69一区二区三区| 精品偷拍激情视频在线观看| 国产午夜在线| 2021天堂中文幕一二区在线观| 在线午夜视频| 九九99九九精彩| 久热免费视频| 国产有码在线| 9999在线视频| 午夜免费福利在线观看| 国产在线更新| 中文字幕免费中文| 国产精品欧美韩国日本久久| 亚洲精品天堂在线| 成人福利视频导航| 国产h色视频在线观看| 国产在线视频精品视频免费看| 国产激情自拍| 天天操天天操一操| 国产精品久久久久久福利| 中文av字幕| 午夜视频在线免费| 欧美精品小视频| 国产福利电影在线观看| 天海翼中文字幕| 国产一级激情| 免费精品国产自产拍观看| 国产精品伦一区二区三区视频| 国产在线色视频| 免费一区二区在线观看| 亚洲人成影院在线| 在线视频中文字幕| 18av在线播放| 精品伦理一区二区| 国产夫妻视频| 91桃色在线| 在线欧美一级视频| 精品乱码一区二区三四区视频| 国产网站在线播放| 国产青草视频在线观看视频| 国产亚洲精品午夜高清影院| 国产视频三区| 国产小视频福利在线| 国产精品久久人| 国产91久久久久蜜臀青青天草二| 国产精品久久久高清免费| 国产极品美女到高潮| 777电影在线观看| 伊人影院在线视频| 欧美韩日国产| 国产三级视频| 亚洲第一成人在线视频| 激情综合网五月激情| 午夜av电影| 一色桃子av在线| 九九精品九九| 91精品国产91久久久久久青草| 国产黄大片在线观看画质优化| 精品视频一二三| 九九在线视频| 精品亚洲成a人片在线观看| 亚洲夜夜综合| 国产性色视频| 欧美日韩国产亚洲沙发| 国产精品视频一区二区久久| 天天干天天摸| 国产精品视频二区三区| eeuss在线观看| 国产无遮挡又黄又爽免费软件 | 国产免费电影网站入口| 国产精品第八页| 四虎免费视频| 精品国产99久久久久久| 中文字幕在线视频网| 亚洲欧美中文字幕在线观看| 国产视频一二区| 国产在线你懂得| www.三区| 依依成人在线| 97在线超碰| 中文天堂av| 国产精品久久久久久久久鸭| 中文字幕视频在线| 国自产拍在线网站网址视频| 香蕉视频在线观看www| 天天操夜夜操天天射| 三级小说一区| 亚洲社区在线| 阿v免费在线观看| 免费av不卡在线观看| 欧美专区日韩| 国产在线观看a视频| 激情综合丁香| 国产69精品久久久久孕妇国产69久久| 日本电影全部在线观看网站视频| jizz在线免费观看| 亚洲第一成年免费网站| 亚洲天堂视频在线观看免费| 在线国产三级| 欧美a免费在线| 福利在线观看| 丁香视频免费观看| 国产三区四区在线观看| 国产福利免费观看| 在线视频二区| 成视频年人免费看黄网站| 99视频资源网| 一区二区三区免费视频网站| 免费高清av| 国产极品视频| 开心婷婷激情五月| 国产青青草在线| 四虎成人免费观看在线网址| 国产69精品久久app免费版| 五月亚洲综合| 色综合久久五月天| 狠狠狠综合7777久夜色撩人| 国产精品国产三级国产试看| 亚洲精品国自产拍在线观看| 青青青青在线| 国产精品入口麻豆高清| av小说在线| 国产午夜视频在线观看| 午夜在线不卡| 国产传媒在线播放| 黄色国产网站在线播放| 国产www视频在线观看| 欧美亚洲另类在线观看| 国产黄色av免费看| 国产免费永久在线观看| 亚洲综合天堂网| 最近高清中文在线字幕在线观看| 91九色在线看| 国产三级在线看| 成人午夜无人区一区二区| 亚洲精品视频区| 在线视频观看国产| 国产网友自拍视频导航网站在线观看| 人人干人人插| 人人澡人人爽| a级在线观看| 亚洲视频手机在线观看| 国产对白叫床清晰在线播放| 国产精品午夜久久久久久| 免费a在线观看| 久久综合精品视频| 亚洲人在线播放| 亚洲电影视频在线| 亚洲精品aaaa| 亚洲日本久久久午夜精品| av男人的天堂网| 一色桃子av在线| 在线观看的av网站| 亚洲字幕成人中文在线观看| 在线免费黄色毛片| 香蕉视频网站在线观看| 亚洲成年人视频| 欧美xxxx黑人又粗又长| 欧美日韩一区二区三区在线播放| a视频在线观看| 国自产拍在线网站网址视频| 快射av在线播放一区| 国产尤物视频| 国产系列电影在线播放网址| 国产精品视频一区二区三区麻豆| 国产盗摄精品一区二区酒店| 一级黄色av| 国产农村av| 精品国产99久久久久久| 在线天堂av| 国产在线一区二区视频| 国产网站在线免费观看| 国产www网站| 超碰免费在线播放| 国产精品合集一区二区| 精品视频二区三区| av在线不卡网站| 国产一级黄色片免费| 精品99又大又爽又硬少妇毛片| 日本国产在线| 国产区高清在线| 久久精品国产麻豆| 2018中文字幕在线观看| 欧美性猛交p30| 中文av资源在线| 国产自产视频| 日本在线观看| 91国内精品久久久久| 天天爱天天做色综合| eeuss影院在线观看| 国产三区在线观看| а√资源新版在线天堂| 国产精品xxx电影|