如何处理CouchDb文档中的多个外键?
博客场景示例 有三个实体:帖子、评论和作者(评论) 我希望收到格式为:Comment.Header Post.Header Author.Name的评论列表 邮递 身份证 标题 正文 作者 身份证 名称 评论 身份证 标题 正文 张贴 作者如何处理CouchDb文档中的多个外键?,couchdb,Couchdb,博客场景示例 有三个实体:帖子、评论和作者(评论) 我希望收到格式为:Comment.Header Post.Header Author.Name的评论列表 邮递 身份证 标题 正文 作者 身份证 名称 评论 身份证 标题 正文 张贴 作者 使用SQL连接很简单,但我不知道如何在CouchDb中做到这一点,而不需要对每个注释的数据库发出额外的请求,这是完全不可行的。让我们假设您拥有以下实体: 职位 作者 { "_id": "bbd998617a479940eb536cc84200
使用SQL连接很简单,但我不知道如何在CouchDb中做到这一点,而不需要对每个注释的数据库发出额外的请求,这是完全不可行的。让我们假设您拥有以下实体: 职位 作者
{
"_id": "bbd998617a479940eb536cc842002322",
"_rev": "1-aab8fd1832046602fed1cad425a98c0f",
"name": "Example Author",
"type": "author"
}
评论
{
"_id": "bbd998617a479940eb536cc84200280c",
"_rev": "2-f311bd9ab26867f924a837b0c0f76954",
"type": "comment",
"post": "bbd998617a479940eb536cc842000630",
"author": "bbd998617a479940eb536cc842002322",
"text": "Comment Text Blah Blah Blah"
}
可以使用此设计文档生成生成所需结果的索引:
{
"_id": "_design/query",
"_rev": "9-f441a082e47b2cb51c72d001d9b411e3",
"views": {
"query": {
"map": function(doc) {
if (doc.type && doc.type=="comment") {
emit([doc._id],{ "_id":doc._id});
emit([doc._id, "author"],{ "_id":doc.author});
emit([doc._id, "post"],{ "_id":doc.post});
}
}
}
}, "lists" : {
"listname":function(head,req){FUNCTION_BODY}
}
"language": "javascript"
}
第一个emit将返回注释文档,第二个emit和第三个emit将分别返回作者和帖子
然后,您可以使用reduce函数将查询结果简化为必填字段,并最终在需要时使用_list函数格式化结果
获取JSON输出的示例_列表:
function (head, req) {
var row;
var i=0;
var comments=[];
while(row = getRow()){
var comment_index=Math.floor(i/3);
if(i%3==0){
comments[comment_index] = {};
comments[comment_index]["comment_text"]= row.doc.text;
}
else if(i%3==1){
comments[comment_index]["author_name"]= row.doc.name;
}
else if(i%3==2){
comments[comment_index]["post_header"]= row.doc.Header;
}
i++;
}
send(JSON.stringify(comments));
}
然后通过调用视图(您必须包括include_docs):假设您有以下实体: 职位 作者
{
"_id": "bbd998617a479940eb536cc842002322",
"_rev": "1-aab8fd1832046602fed1cad425a98c0f",
"name": "Example Author",
"type": "author"
}
评论
{
"_id": "bbd998617a479940eb536cc84200280c",
"_rev": "2-f311bd9ab26867f924a837b0c0f76954",
"type": "comment",
"post": "bbd998617a479940eb536cc842000630",
"author": "bbd998617a479940eb536cc842002322",
"text": "Comment Text Blah Blah Blah"
}
可以使用此设计文档生成生成所需结果的索引:
{
"_id": "_design/query",
"_rev": "9-f441a082e47b2cb51c72d001d9b411e3",
"views": {
"query": {
"map": function(doc) {
if (doc.type && doc.type=="comment") {
emit([doc._id],{ "_id":doc._id});
emit([doc._id, "author"],{ "_id":doc.author});
emit([doc._id, "post"],{ "_id":doc.post});
}
}
}
}, "lists" : {
"listname":function(head,req){FUNCTION_BODY}
}
"language": "javascript"
}
第一个emit将返回注释文档,第二个emit和第三个emit将分别返回作者和帖子
然后,您可以使用reduce函数将查询结果简化为必填字段,并最终在需要时使用_list函数格式化结果
获取JSON输出的示例_列表:
function (head, req) {
var row;
var i=0;
var comments=[];
while(row = getRow()){
var comment_index=Math.floor(i/3);
if(i%3==0){
comments[comment_index] = {};
comments[comment_index]["comment_text"]= row.doc.text;
}
else if(i%3==1){
comments[comment_index]["author_name"]= row.doc.name;
}
else if(i%3==2){
comments[comment_index]["post_header"]= row.doc.Header;
}
i++;
}
send(JSON.stringify(comments));
}
然后通过调用您的视图(您必须包括include_docs):注释是否嵌套在post文档中?不,为了实验起见,让我们想象一下,它们应该分开保存。我想知道CouchDb中是否有解决多个外键问题的模式。注释是否嵌套在post文档中?不,为了实验起见,让我们想象一下,它们应该分开保存。我想知道CouchDb中是否有解决多个外键问题的模式。@EugeneKr您需要reduce/_list函数语法吗?谢谢Fady,看来我们走对了路。请提供reduce/_list的语法。谢谢Fady,我理解这背后的想法,但是列表函数的代码不起作用。我已经修复了它。函数(head,req){var row;var I=0;var comments=[];而(true){comments[I]={}for(var j=0;j<3;++j){row=getRow();if(!row)break;开关(j){case 0:comments[I][“comment_text”]=row.doc.text;break案例1:comments[I][“author_name”]=row.doc.name;break case 2:comments[i][“post_header”]=row.doc.header;break}如果(!row)break;++i;}发送(JSON.stringify(comments));}请查看并使用提供的固定代码更新您的答案(已测试)。然后我接受答案。@EugeneKr您需要reduce/_list函数语法吗?谢谢Fady,我们似乎走在正确的道路上。请提供reduce/_list的语法。谢谢Fady,我理解这背后的想法,但是您的list函数代码不起作用。我已经修复了它。function(head,req){var row;var i=0;var comments=[];while(true){comments[i]={}for(var j=0;j<3;++j){row=getRow();if(!row)break;switch(j){case 0:comments[i][“comment_text”]=row.doc.text;break案例1:comments[i][“author_name”]=row.doc.name;break case 2:comments[i][“post_header”]=row.doc.header;break}如果(!row)break;++i;}发送(JSON.stringify(comments));}请查看并使用提供的固定代码更新您的答案(已测试)。然后我将接受答案。