当前位置: 首页 > 科技观察

在Postgres中克隆一个MongoDB

时间:2023-03-20 13:37:34 科技观察

世上没有路,走的人多了,就成了路。为什么不能在Postgres上构建MongoDB?在NoSQL采取一系列行动后,Postgres社区并没有坐以待毙。Postgres一直在改进:集成JSON和PLV8。PLV8引入了V8Javascript引擎。操作JSON也更容易(需要验证)。开始前要做的事情:Postgres9.2+(截至本博客条目,9.2处于测试阶段)-http://www.postgresql.org/ftp/source/V8-https://github.com/v8/v8PLV8-http://code.google.com/p/plv8js/wiki/PLV8MongoDB的最低级别是集合。集合可以用表表示:CREATETABLEsome_collection(some_collection_idSERIALNOTNULLPRIMARYKEY,dataJSON);StringJSON存储在一个Postgres表中,简单易行(现在看起来像这样)。以下自动创建一个集合。保存在集合表中:CREATETABLEcollection(collection_idSERIALNOTNULLPRIMARYKEY,nameVARCHAR);--makesurethenameisuniqueCREATEUNIQUEINDEXidx_collection_constraintONcollection(name);一旦表建好,就可以通过存储过程自动存储创建一个集合。方法是先建表,再插入建表序列。CREATEORREPLACEFUNCTIONcreate_collection(collectionvarchar)RETURNSbooleanAS$$varplan1=plv8.prepare('INSERTINTOcollection(name)VALUES($1)',['varchar']);varplan2=plv8。prepare('CREATETABLEcol_'+collection+'(col_'+collection+'_idINTNOTNULLPRIMARYKEY,dataJSON)');varplan3=plv8.prepare('CREATESEQUENCEseq_col_'+collection);varret;try{plv8.subtransaction(function(){plan1.execute([collection]);plan2.execute([]);plan3.execute([]);ret=true;});}catch(err){ret=false;}plan1.free();plan2.free();plan3.free();returnret;$$LANGUAGEplv8IMMUTABLESTRICT;有了存储过程,就多了已经很方便了:SELECTcreate_collection('my_collection');解决了集合存储的问题,我们来看看MongoDB的数据分析。MongoDB通过点注解的方式完成这个动作:CREATEORREPLACEFUNCTIONfind_in_obj(datajson,keyvarchar)RETURNSVARCHARAS$$varobj=JSON.parse(data);varparts=key.split('.');varpart=parts.shift();while(part&&(obj=obj[part])!==undefined){part=parts.shift();}//thiswilleitherbethevalue,orundefinedreturnobj;$$LANGUAGEplv8STRICT;以上函数返回的是VARCHAR,并不是适用于所有情况,但是很有用对于字符串比较:SELECTdataFROMcol_my_collectionWHEREfind_in_obj(data,'some.element')='somethingcool'除了字符串比较,MongoDB还提供了数值类型的比较,并提供了关键字exists。以下是find_in_obj()方法的不同实现:CREATEORREPLACEFUNCTIONfind_in_obj_int(datajson,keyvarchar)RETURNSINTAS$$varobj=JSON.parse(data);varparts=key.split('.');varpart=parts.shift();while(part&&(obj=obj[part])!==undefined){part=parts.shift();}returnNumber(obj);$$LANGUAGEplv8STRICT;CREATEORREPLACEFUNCTIONfind_in_obj_exists(datajson,keyvarchar)RETURNSBOOLEANAS$$varobj=JSON.parse(data);varparts=key.split('.');varpart=parts.shift();while(part&&(obj=obj[part])!==undefined){part=parts.shift();}return(obj===undefined?'f':'t');$$LANGUAGEplv8STRICT;接下来是数据查询。Find()是通过现有材料方法实现的。#p#在本节中将介绍保存数据和从MongDB查询构建WHERE子句,以便检索我们已经写入的保存数据到集合中的数据很简单。首先,我们需要检查JSON对象并查找_id值。这部分代码本身假设如果_id已经存在则表示更新,否则表示插入。注意我们还没有创建objectID,只是用了一个序列等待它发生:CREATEORREPLACEFUNCTIONsave(collectionvarchar,datajson)RETURNSBOOLEANAS$$varobj=JSON.parse(data);varid=obj._id;//ifthereisnoid,naivelyassumeaninsertif(id===undefined){//getthenextvaluefromthesequencefortheIDvarseq=plv8.prepare("SELECTnextval('seq_col_"+collection+"')ASid");varrows=seq.execute([]);id=rows[0].id;对象。_id=id;seq.free();varinsert=plv8.prepare("插入col_"+collection+"(col_"+collection+"_id,data)VALUES($1,$2)",['int','json']);insert.execute([id,JSON.stringify(obj)]);insert.free();}else{varupdate=plv8.prepare("UPDATEcol_"+collection+"SETdata=$1WHEREcol_"+collection+"_id=$2",['json','int']);update.execute([data,id]);}returntrue;$$LANGUAGEplv8IMMUTABLESTRICT;基于这个视图,我们可以构造一些简单的文档用于插入:{"name":"JaneDoe","address":{"street":"123FakeStreet","city":"Portland","state":"OR"},"age":33}{"name":"SarahSmith","address":{"street":"456RealAve","city":"Seattle","state":"WA"}}{"name":"JamesJones","address":{"street":"789InfinityWay","city":"Oakland","state":"CA"},"age":23}让我们创建一个集合并插入一些数据:work=#SELECTcreate_collection('data');create_collection--------------------t(1row)work=#SELECTsave('data','{ourobject}');save------t(1row)英文原文:BuildingaMongoDBCloneinPostgres:Part1翻译链接:http://www.oschina.net/translate/building_a_mongodb_clone_in_postgres_part_1