当前位置:  开发笔记 > 编程语言 > 正文

CouchDB视图使用来自两个独立文档的嵌入式数组组成JSON对象

如何解决《CouchDB视图使用来自两个独立文档的嵌入式数组组成JSON对象》经验,为你挑选了1个好方法。

假设我在CouchDB数据库中存储了两种类型的文档.首先是财产类型设置为联系,第二个是电话.联系人类型文档有另一个名为name的属性.电话类型具有属性编号和contact_id,以便它可以引用联系人.这是微不足道的一对多的场景,其中一个联系人可以有N个电话号码(我知道他们可以嵌入单一接触文件,但我需要证明一个与不同的文件一对多的关系).

Scott的原始示例数据有2个电话号码,Matt有1个号码:

{_id: "fc93f785e6bd8c44f14468828b001109", _rev: "1-fdc8d121351b0f5c6d7e288399c7a5b6", type: "phone", number: "123456", contact_id: "fc93f785e6bd8c44f14468828b00099f"}
{_id: "fc93f785e6bd8c44f14468828b000f6a", _rev: "1-b2dd90295693dc395019deec7cbf89c7", type: "phone", number: "465789", contact_id: "fc93f785e6bd8c44f14468828b00099f"}
{_id: "fc93f785e6bd8c44f14468828b00099f", _rev: "1-bd643a6b0e90c997a42d8c04c5c06af6", type: "contact", name: "Scott"}
{_id: "16309fcd03475b9a2924c61d690018e3", _rev: "1-723b7c999111b116c353a4fdab11ddc0", type: "contact", name: "Matt"}
{_id: "16309fcd03475b9a2924c61d69000aef", _rev: "3-67193f1bfa8ed21c68e3d35847e9060a", type: "phone", number: "789456", contact_id: "16309fcd03475b9a2924c61d690018e3"}

地图功能:

function(doc) {
  if (doc.type == "contact") {
    emit([doc._id, 1], doc);
  } else if (doc.type == "phone") {
    emit([doc.contact_id, 0], doc);
  }
}

减少功能:

function(keys, values) {
  var output = {};

  for(var elem in values) {
    if(values[elem].type == "contact") {
      output = {
        "ID": values[elem]._id,
        "Name": values[elem].name,
        "Type": values[elem].type,
        "Phones": []
      };
    } else if (values[elem].type == "phone") {
      output.Phones.push({ 
        "Number": values[elem].number, 
        "Type": values[elem].type 
      });
    }
  }

  return output;
}

由于Map函数中的键,group_level设置为1.现在我可以通过附带的手机获取我的联系人,例如:

http://localhost:5984/testdb2/_design/testview/_view/tv1?group_level=1

或者像这样搜索与startkey和endkey的某些联系:

http://localhost:5984/testdb2/_design/testview/_view/tv1?group_level=1&startkey=[%22fc93f785e6bd8c44f14468828b00099f%22]&endkey=[%22fc93f785e6bd8c44f14468828b00099f%22,{}]

结果看起来正是我想要的 - 联系人将根据一对多关系嵌入手机.这就是问题:这是如何在CouchDB中使用MapReduce函数的正确方法吗?使用此方法时是否存在任何显着的性能问题?



1> Ben Damman..:

一般来说,如果不这样做,则使用较少的磁盘空间emit(...,doc).

您可能想要重新考虑具有reduce功能.实际上没有必要获得您需要的数据.例如,如果您拥有大量记录,则以下内容可能会占用更少的磁盘空间并执行得更好.

此外,我认为在文件包含的reduce函数中构建更多数据是违反CouchDB的.在这种情况下你不是那样做的,但是你遵循的模式可能会导致你以后遇到麻烦.它被称为减少是有原因的.:-)

所以像这样的东西更像CouchDB方式:

function(doc) {
  if (doc.type == "contact") {
    emit([doc._id, 0], {
        "Name": doc.name,
        "Type": doc.type
    });
  } else if (doc.type == "phone") {
    emit([doc.contact_id, 1], {
        "Number": doc.number,
        "Type": doc.type
    });
  }
}
emit(...,doc)

查询特定联系人,如下所示:

http://localhost:5984/testdb2/_design/testview/_view/tv1?
  startkey=[%22fc93f785e6bd8c44f14468828b00099f%22, 0]
  &endkey=[%22fc93f785e6bd8c44f14468828b00099f%22,1]

当然,你没有得到与以前相同的JSON结构的结果,但我相信这在CouchDB中表现更好.

推荐阅读
可爱的天使keven_464
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有