如何处理CouchDb文档中的多个外键?

如何处理CouchDb文档中的多个外键?,couchdb,Couchdb,博客场景示例 有三个实体:帖子、评论和作者(评论) 我希望收到格式为:Comment.Header Post.Header Author.Name的评论列表 邮递 身份证 标题 正文 作者 身份证 名称 评论 身份证 标题 正文 张贴 作者 使用SQL连接很简单,但我不知道如何在CouchDb中做到这一点,而不需要对每个注释的数据库发出额外的请求,这是完全不可行的。让我们假设您拥有以下实体: 职位 作者 { "_id": "bbd998617a479940eb536cc84200

博客场景示例

有三个实体:帖子、评论和作者(评论) 我希望收到格式为:Comment.Header Post.Header Author.Name的评论列表

邮递 身份证 标题 正文

作者 身份证 名称

评论 身份证 标题 正文 张贴 作者


使用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));}请查看并使用提供的固定代码更新您的答案(已测试)。然后我将接受答案。