Join CouchDB中的多连接

Join CouchDB中的多连接,join,couchdb,nosql,Join,Couchdb,Nosql,我目前正试图弄清楚CouchDB是否适合我的用例,如果适合,如何适合。我的情况与以下类似: 第一组文档(我们称之为公司): 第二组文档(我们称之为项目): 第三组文档(我们称之为事件): 简言之,每个公司都有多个项目,每个项目都可能有多个事件。我对数据建模的一个原因是,我主要来自SQL背景,因此建模可能完全不合适。第二个原因是,我想通过使用couchdb提供的REST-API非常轻松地添加新事件。因此,事件必须是单一文件 然而,我现在想得到一个视图,使我能够计算每个公司的总成本。我可以使用map

我目前正试图弄清楚CouchDB是否适合我的用例,如果适合,如何适合。我的情况与以下类似:

第一组文档(我们称之为公司):

第二组文档(我们称之为项目):

第三组文档(我们称之为事件):

简言之,每个公司都有多个项目,每个项目都可能有多个事件。我对数据建模的一个原因是,我主要来自SQL背景,因此建模可能完全不合适。第二个原因是,我想通过使用couchdb提供的REST-API非常轻松地添加新事件。因此,事件必须是单一文件

然而,我现在想得到一个视图,使我能够计算每个公司的总成本。我可以使用map reduce和链接文档轻松定义一个视图,从而获得每个项目的总金额。然而,一旦我进入了项目层面,我就无法进一步提升到公司层面


使用couchDb有可能做到这一点吗?这种数据汇总听起来像是map reduce的完美用例。在SQL中,我只想做一个三表联接,但在couchDb中,似乎我能得到的最好结果是两个表联接。

如前所述,您不能在couchDb中进行联接,但这不是一个限制,这是一种邀请,让您思考您的问题并以不同的方式处理它们。在CouchDb中执行此操作的正确方法是定义数据结构,例如:
IncidentReference
由以下内容组成:

  • 项目id
  • 公司的身份证呢
这样,您的数据将如下所示:

{
   "_id" : "301",
   "project" : 4,
   "description" : "...",
   "cost" : 400,
   "reference" : {
         "projectId" : 1,
         "companyId" : 2
   }
}

这很好。一旦你有了它,你就可以使用Map/Reduce轻松实现你想要的任何东西。一般来说,您需要考虑查询数据的方式。

您不能(或至少不应该)在CouchDB中进行任何连接。您可以使用列表函数合并相邻行(排序规则),但任何其他操作都会破坏您的性能。据我所知,从SQL的角度来看,您必须真正放弃任何形式的规范化吗?因为有了这个附带的引用,我现在将projectId和companyId都存储在引用中,尽管项目已经包含了公司(重复数据)。那么,防止这些数据变得不一致的最佳方法是什么呢?通常来说,您仍然需要注意非规范化,例如,如果您对客户名称进行了非规范化,并且该名称发生了变化,那么这将变得很难管理。但是,根据需要对其他实体进行尽可能多的引用(标识符)通常是安全的。如果你想一想,这些参考资料变得过时是非常罕见的(一个事件怎么可能不再属于这个项目?或者这个公司)。只需确保这些引用参与定义文档的标识,标识不会更改:)
{
    "_id" : 4,
    "name" : "FooProject1",
    "company" : 1
}

{
    "_id" : 5,
    "name" : "FooProject2",
    "company" : 1
}
...
{
    "_id" : 100,
    "name" : "BazProject2",
    "company" : 3
}    
{
   "_id" : "300",
   "project" : 4,
   "description" : "...",
   "cost" : 200
}

{
   "_id" : "301",
   "project" : 4,
   "description" : "...",
   "cost" : 400
}

{
   "_id" : "302",
   "project" : 4,
   "description" : "...",
   "cost" : 500
}
   ...
{
   "_id" : "301",
   "project" : 4,
   "description" : "...",
   "cost" : 400,
   "reference" : {
         "projectId" : 1,
         "companyId" : 2
   }
}