这篇文章主要介绍“怎么在PostgreSQL的基础上创建一个MongoDB的副本”,在日常操作中,相信很多人在怎么在PostgreSQL的基础上创建一个MongoDB的副本问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”怎么在PostgreSQL的基础上创建一个MongoDB的副本”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

开始前需要做的准备:

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的最低级别是集合. 集合可以用表来表示:

CREATETABLEsome_collection(some_collection_idSERIALNOTNULLPRIMARYKEY,dataJSON);

字符型的JSON 被保存在 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() 方法.
保存数据到集合中很简单。首先,我们需要检查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;obj._id=id;seq.free();varinsert=plv8.prepare("INSERTINTOcol_"+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)

你可以通过检查“col_data”表的内容来查看对象。

其它翻译版本(1)

现在我们已经有了一些数据,让我们再查询一下。假设我们想查找住在俄勒冈或华盛顿州年龄大于30的所有人,使用一个MongoDB风格的find():

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

因为上次我们已经创建了一些深度的包检测,现在就很容易创建查询并返回Jane Doe:

SELECTdataFROMcol_dataWHEREfind_in_obj_int(data,'age')>30AND(find_in_obj(data,'address.state')='OR'ORfind_in_obj(data,'address.state')='WA')

我采用了写一个递归调用函数来建立WHERE子句的方法。它有点长,所以我没有把它贴在这里而是放在GitHub上。一旦find()存储过程被创建,我们就可以在查询中使用它。我们应该能够看到Jane Doe被返回:

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

到此,关于“怎么在PostgreSQL的基础上创建一个MongoDB的副本”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注亿速云网站,小编会继续努力为大家带来更多实用的文章!