在couchDB中表示多对多关系

在couchDB中表示多对多关系,couchdb,nosql,non-relational-database,Couchdb,Nosql,Non Relational Database,假设我正在编写一个日志分析应用程序。主域对象将是一个日志条目。此外应用程序的用户定义一个日志主题,描述他们感兴趣的日志条目。当应用程序接收到日志条目时,它会将它们添加到couchDB中,并根据系统中的所有日志主题检查它们是否符合主题中的条件。如果是,则系统应记录条目与主题匹配。因此,日志条目和日志主题之间存在多对多关系 如果我将其存储在RDBMS中,我会执行以下操作: CREATE TABLE Entry ( id int, ... ) CREATE TABLE Topic ( id i

假设我正在编写一个日志分析应用程序。主域对象将是一个日志条目。此外应用程序的用户定义一个日志主题,描述他们感兴趣的日志条目。当应用程序接收到日志条目时,它会将它们添加到couchDB中,并根据系统中的所有日志主题检查它们是否符合主题中的条件。如果是,则系统应记录条目与主题匹配。因此,日志条目和日志主题之间存在多对多关系

如果我将其存储在RDBMS中,我会执行以下操作:

CREATE TABLE Entry (
 id int,
 ...
)

CREATE TABLE Topic (
 id int,
 ...
)

CREATE TABLE TopicEntryMap (
 entry_id int,
 topic_id int
)
{
  'type':'LogTopicToLogEntryMap',
  'topic_id':'topic_12',
  'entry_id':'entry_15'
}
使用CouchDB,我第一次尝试只使用两种文档类型。我有一个日志条目类型,看起来像这样:

{
  'type': 'LogEntry',
  'severity': 'DEBUG',
  ...
}
{
  'type': 'LogTopic',
  'matching_entries': ['log_entry_1','log_entry_12','log_entry_34',....],
  ...
}
我有一个日志主题类型,看起来像这样:

{
  'type': 'LogEntry',
  'severity': 'DEBUG',
  ...
}
{
  'type': 'LogTopic',
  'matching_entries': ['log_entry_1','log_entry_12','log_entry_34',....],
  ...
}
您可以看到,我通过在每个LogTopic文档中使用
匹配_entries
字段来存储LogEntry文档id列表来表示关系。这在某种程度上是可行的,但当多个客户端都试图向一个主题添加匹配条目时,我会遇到问题。两个都尝试乐观更新,一个失败。我现在使用的解决方案基本上是复制RDBMS方法,并添加第三种文档类型,如:

CREATE TABLE Entry (
 id int,
 ...
)

CREATE TABLE Topic (
 id int,
 ...
)

CREATE TABLE TopicEntryMap (
 entry_id int,
 topic_id int
)
{
  'type':'LogTopicToLogEntryMap',
  'topic_id':'topic_12',
  'entry_id':'entry_15'
}
这是可行的,并克服了并发更新问题,但我有两个保留意见:

  • 我担心我只是在用这个 方法,因为这是我在 关系数据库。我不知道有没有 一个更像couchDB的(relaxful?) 解决方案
  • 我的观点不再适用 检索一个项目的所有条目 一次通话中的特定主题。我的 以前的解决方案允许(如果我 使用了include_docs参数)

  • 有谁能给我一个更好的解决方案吗?如果我也发布我正在使用的视图会有帮助吗?

    你的方法很好。使用CouchDB并不意味着您将放弃关系建模。您需要运行两个查询,但这是因为这是一个“连接”。带有连接的SQL查询也很慢,但SQL语法允许您在一条语句中表达查询

    在我使用CouchDB的几个月的经验中,我发现:

  • 没有模式,因此设计应用程序模型既快速又灵活
  • CRUD就在那里,所以开发应用程序既快速又灵活
  • 再见SQL注入
  • 什么是SQL连接需要在CouchDB中做更多的工作

  • 根据您的需要,我发现couchdb-lucene对于构建更复杂的查询也很有用。

    我将这个问题交叉发布到由Christopher Lenz编写的Nathan Stott a上。

    我会尝试设置关系,以便Logentry知道它们属于哪个日志主题。这样,插入日志条目不会产生冲突,因为日志主题不需要更改

    然后,一个简单的map函数将为它所属的每个LogTopic发出一次LogEntry,基本上动态地构建您的TopicEntryMap:

    "map": function (doc) {
        doc.topics.map(function (topic) {
            emit(topic, doc);
        });
    }
    

    这样,使用
    ?key=
    参数查询视图将为您提供属于某个主题的所有条目。

    +1最后,自从我了解couchdb和mongodb以来,我一直有这个问题。我知道有人有答案。这是一篇非常好的博客文章,但它是关于一对多的关系(博客评论)。有关于如何处理多对多的例子吗?