Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/477.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/72.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在MongoDB中用属性表示多对多关系的最佳模型_Javascript_Mysql_Mongodb_Meteor_Nosql - Fatal编程技术网

Javascript 在MongoDB中用属性表示多对多关系的最佳模型

Javascript 在MongoDB中用属性表示多对多关系的最佳模型,javascript,mysql,mongodb,meteor,nosql,Javascript,Mysql,Mongodb,Meteor,Nosql,表示具有属性的多对多关系的最“mongo”方式是什么 例如: 简介 MYSQL表 人=>名、姓、… 电影=>名称、长度.. peopleMovies=>movieId、人名、语言、角色 解决方案1 把人植入电影 在MongoDB中,我理解将非规范化并嵌入是件好事,但我不想将人嵌入电影,这在逻辑上毫无意义。因为人们不一定只属于电影 解决方案2 人物和电影将是两个独立的集合。 People=>embed[{movieId:12,personId:1,语言:“英语”,角色:“Main”}…] 电

表示具有属性的多对多关系的最“mongo”方式是什么

例如:

简介
MYSQL表

=>
名、姓、…

电影
=>
名称、长度..

peopleMovies
=>
movieId、人名、语言、角色

解决方案1
把人植入电影

在MongoDB中,我理解将
非规范化并嵌入
是件好事,但我不想
人嵌入电影,这在逻辑上毫无意义。因为人们不一定只属于电影

解决方案2
人物
电影
将是两个独立的集合。
People
=>embed
[{movieId:12,personId:1,语言:“英语”,角色:“Main”}…]

电影
=>嵌入
[{movieId:12,personId:1,语言:“英语”,角色:“Main”}…]

此解决方案的问题是,当我们要为特定的
电影
更新一个人的
角色时,我们需要运行两个更新查询,以确保两个集合中的数据同步

解决方案3
我们还可以做一些关系性更强的事情,比如最终得到三个集合

=>
名、姓、…
电影
=>
名称、长度..
演员
=>
电影ID、人物ID、语言、角色

问题是,由于MongoDB中缺少join语句,因此从people->movies开始需要
3次查询
,反之亦然


这里是我的问题,在
MongoDB
中,还有哪些其他方法可以以更
NoSQL
的方式对类似的东西进行建模。就提供的解决方案而言,在mongo中,哪一个在性能和惯例方面最好。

meteor的API在许多方面鼓励使用扁平关系文档,但是MongoDB是一个非关系数据存储。不幸的是,这一冲突留给开发人员解决

模式结构和连接的概念是一个需要在单个答案中涵盖的庞大主题,因此我将尝试尽可能简洁

选择关系模型的原因 假设您有评论和帖子数据。考虑如果你在你的文章中嵌入评论,将会发生什么。

  • DDP对文件进行操作。每次在同一帖子中添加新评论时,都会发送所有评论

  • 允许
    拒绝
    规则对文档进行操作。期望同样的规则同时适用于帖子和评论可能是不合理的

  • 出版物往往在收藏方面更有意义。在上述场景中,我们无法轻松发布独立于其帖子的评论列表

  • 关系数据库的存在有很好的理由。其中之一是避免第二个解决方案中固有的多次修改问题

选择嵌入式模型的原因
  • MongoDB本机不支持连接,并且没有生成反应连接的核心包
建议 使用第三种解决方案。根据我的经验,选择关系模型的原因远远超过了数据存储所施加的限制。当然,克服连接的缺乏并不容易,但痛苦可能只限于少数发布函数。以下是我极力推荐的一些资源:

  • 在偶发的梦中。Chris详细介绍了您的具体用例,但是他使用observe回调手动执行反应式连接,我不推荐这样做

  • 从。这涵盖了如何以及为什么应该进行反应式连接的基本知识

  • 来自的非规范化章节。这涵盖了我上面提到的许多要点,还讨论了何时以及如何对一些数据进行非规范化

  • 您可以使用来加入数据。其他软件包包括:、和


如果您需要更多信息,请在下面进行评论,我将更新我的答案。

我认为您应该对您的收藏进行非规范化。设计MongoDB集合和文档时,重要的一点是考虑您的视图。显示视图需要哪些数据?其想法是,您应该尝试将这些数据作为文档的一部分

例如,在您的例子中,您可能有一个
电影
视图,您希望在其中显示有关电影的信息。但是关于电影的页面可能只需要每个人的基本信息(名字、姓氏、照片URL)。不是所有其他的事情。反之亦然,关于一个人的页面可能会列出所有电影,但也同样只需要关于每部电影的信息子集,如标题、年份和海报照片URL

因此,一种选择是有两个集合,但然后在集合之间嵌入(非规范化)所需的那个些字段。例如,
Movies
collection将有一个字段
people
,它是一个子文档数组。而
People
集合将具有
movies
字段,该字段将是一个子文档数组,以及那些您想要指定角色的额外字段,依此类推

因此,文档可能如下所示。电影:

{
  _id: "AAA",
  title: "...",
  year: 2015,
  length: 120,
  posterURL: "...",
  people: [
    {
      person: {
        _id: "BBB",
        firstName: "...",
        lastName: "...",
        photoURL: "..."
      },
      role: "..."
    }
  ]
}
{
  _id: "AAA",
  title: "...",
  year: 2015,
  length: 120,
  posterURL: "..."
}
市民:

{
  _id: "BBB",
  firstName: "...",
  lastName: "...",
  photoURL: "...",
  movies: [
    {
      _id: "AAA",
      title: "...",
      year: 2015,
      posterURL: "..."
    }
  ]
}
{
  _id: "BBB",
  firstName: "...",
  lastName: "...",
  photoURL: "..."
}
当然,问题是如何保持这些字段同步。如果您更新了电影的海报照片URL,那么您希望它在所有个人文档中也被更新。为了解决这个问题,我们开发了一个包来定义集合之间的关系,从而确保它们保持同步

因此,在您的情况下,我会在PeerDB中,在CoffeeScript中定义这样的集合:

class People extends Document
  @Meta
    name: 'People'

class Movies extends Document
  @Meta
    name: 'Movies'
    fields: =>
      people: [
        person: @ReferenceField People, ['firstName', 'lastName', 'photoURL'], true, 'movies', ['title', 'year', 'posterURL']
      ]
<
{
  _id: "...",
  movie: {
    _id: "AAA",
    title: "...",
    year: 2015,
    posterURL: "..."
  },
  person: {
    _id: "BBB",
    firstName: "...",
    lastName: "...",
    photoURL: "..."
  },
  role: "..."
}
class People extends Document
  @Meta
    name: 'People'

class Movies extends Document
  @Meta
    name: 'Movies'

class Casting extends Document
  @Meta
    name: 'Casting'
    fields: =>
      person: @ReferenceField People, ['firstName', 'lastName', 'photoURL']
      movie: @ReferenceField Movies, ['title', 'year', 'posterURL']