我正在寻找一个等同于"SQL连接"的CouchDB.
在我的示例中,有些CouchDB文档是列表元素:
{ "type" : "el", "id" : "1", "content" : "first" } { "type" : "el", "id" : "2", "content" : "second" } { "type" : "el", "id" : "3", "content" : "third" }
有一个文档定义了列表:
{ "type" : "list", "elements" : ["2","1"] , "id" : "abc123" }
如您所见,第三个元素已被删除,它不再是列表的一部分.所以它不能成为结果的一部分.现在我想要一个返回内容元素的视图,包括正确的顺序.
结果可能是:
{ "content" : ["second", "first"] }
在这种情况下,元素的顺序已经是应该的.另一个可能的结果
{ "content" : [{"content" : "first", "order" : 2},{"content" : "second", "order" : 1}] }
我开始编写地图功能:
map = function (doc) { if (doc.type === 'el') { emit(doc.id, {"content" : doc.content}); //emit the id and the content exit; } if (doc.type === 'list') { for ( var i=0, l=doc.elements.length; i这是我能得到的.你能纠正我的错误并写一个reduce函数吗?请记住,第三个文档不得是结果的一部分.
当然你也可以写一个不同的地图功能.但是文档的结构(一个definig元素文档和每个条目的条目文档)不能改变.
编辑:不要错过JasonSmith对他的答案的评论,他在那里描述了如何做到这一点.
1> JasonSmith..:谢谢!这是展示CouchDB 0.11新功能的一个很好的例子!
您必须使用与提取相关的数据功能来引用视图中的文档.或者,为了更方便的JSON,使用
_list
函数来清理结果.有关详细信息,请参阅Couchio关于"JOIN"的文章.这是计划:
首先,您的
el
文档具有唯一性约束.如果其中两个id = 2,那就是问题所在.如果是,则必须使用该_id
字段id
.CouchDB将保证唯一性,但此计划的其余部分也需要_id
按ID获取文档.{ "type" : "el", "_id" : "1", "content" : "first" } { "type" : "el", "_id" : "2", "content" : "second" } { "type" : "el", "_id" : "3", "content" : "third" }如果
_id
无法更改要使用的文档,则可以创建一个简单的视图emit(doc.id, doc)
,然后将其重新插入临时数据库.这转化id
为_id
但增加了一些复杂性.视图会发出
{"_id": content_id}
键入的数据[list_id, sort_number]
,以便用其内容"聚集"列表.function(doc) { if(doc.type == 'list') { for (var i in doc.elements) { // Link to the el document's id. var id = doc.elements[i]; emit([doc.id, i], {'_id': id}); } } }现在有一个简单的
el
文档列表,按正确的顺序排列.您可以使用startkey
,endkey
如果您只想查看特定列表.curl localhost:5984/x/_design/myapp/_view/els {"total_rows":2,"offset":0,"rows":[ {"id":"036f3614aeee05344cdfb66fa1002db6","key":["abc123","0"],"value":{"_id":"2"}}, {"id":"036f3614aeee05344cdfb66fa1002db6","key":["abc123","1"],"value":{"_id":"1"}} ]}要获取
el
内容,请使用include_docs=true
.通过魔术_id
,el
文件将加载.curl localhost:5984/x/_design/myapp/_view/els?include_docs=true {"total_rows":2,"offset":0,"rows":[ {"id":"036f3614aeee05344cdfb66fa1002db6","key":["abc123","0"],"value":{"_id":"2"},"doc":{"_id":"2","_rev":"1-4530dc6946d78f1e97f56568de5a85d9","type":"el","content":"second"}}, {"id":"036f3614aeee05344cdfb66fa1002db6","key":["abc123","1"],"value":{"_id":"1"},"doc":{"_id":"1","_rev":"1-852badd683f22ad4705ed9fcdea5b814","type":"el","content":"first"}} ]}请注意,这已经是您需要的所有信息.如果您的客户端非常灵活,您可以使用此JSON解析信息.下一个可选 步骤只需重新格式化以匹配您所需的内容.
使用一个
_list
函数,它只是重新格式化视图输出.人们使用它们来输出XML或HTML,但是我们会使JSON更方便.function(head, req) { var headers = {'Content-Type': 'application/json'}; var result; if(req.query.include_docs != 'true') { start({'code': 400, headers: headers}); result = {'error': 'I require include_docs=true'}; } else { start({'headers': headers}); result = {'content': []}; while(row = getRow()) { result.content.push(row.doc.content); } } send(JSON.stringify(result)); }结果匹配.当然,在生产中,您将需要
startkey
并endkey
指定所需的列表.curl -g 'localhost:5984/x/_design/myapp/_list/pretty/els?include_docs=true&startkey=["abc123",""]&endkey=["abc123",{}]' {"content":["second","first"]}
一句话,这是彻底的.好工作jhs!
这是误导性的.实际上,第2步是一个完整的解决方案,但是,我是详细的背景要求和在客户端增加便利性的可选方法.