如何为 Meteor 构建 mongodb
Posted
技术标签:
【中文标题】如何为 Meteor 构建 mongodb【英文标题】:How to structure your mongodb for Meteor 【发布时间】:2015-04-16 08:48:39 【问题描述】:我对 Meteor 很陌生,我正在尝试弄清楚如何实现一些用例。其中之一是民意调查应用程序。假设您有几个用户可以对几个民意调查进行投票(为简单起见,我们假设民意调查仅限于是/否问题)。 每次使用只能投票一次。
在 SQL 中,我会在 3 个表中对其进行规范化:
USER (id/name)
VOTES (user_id/poll_id/choice)
POLLS (id/question)
但是在 mongodb 的文档存储世界中,似乎鼓励将投票存储在带有投票的集合中,如下所示:
[
_id: 1234
question: "the question"
votes:
[
user_id: 1
choice: 1
]
]
如果用户对投票进行投票,则会将项目插入投票的投票数组中。服务器端必须验证用户尚未投票。 为了获得总分,我必须对投票进行迭代,但当然可以通过在每个投票中创建一个包含汇总得分的字段来改进这一点,该汇总得分会随着投票的添加而更新。
但是,这如何传播给其他用户?假设投票被添加到投票中。整个轮询对象是否会发送到其他连接的客户端?因为如果很多人或投票,投票数组会变大,会导致大量流量......
但在这种情况下,当管理员用户更改问题(并因此将新版本的轮询对象写入集合)时,更新查询需要知道它只应该更新选定的字段。或者如果覆盖整个对象,管理员用户应该拥有该对象的最新版本(因为流星是最后写入获胜的)。
我是否遗漏了一些关于此的最佳实践,或者以与标准化 SQL DB 建模相同的方式对我的集合进行建模确实更容易?
【问题讨论】:
查看我对this question 的回复。我认为使用关系方法(尽管有数据存储)通常是使用流星时的最佳选择。 谢谢大卫。很棒的帖子,很高兴听到在 mongodb 中规范化数据并不是一种罪过。我试图应用 mongo 哲学,但我所有的数据本质上都是相关的。此外,使用嵌入式数据似乎需要我知道我的数据将如何被查询/使用,这在很大程度上我还不知道。 【参考方案1】:Discover Meteor 一书以帖子和评论为例,并建议对数据进行非规范化处理,因此(正如您在问题中所建议的那样)在投票中使用带有 voteCount 属性的单独投票和投票集合。
您投票时的代码如下所示:
// update the poll with a new vote
Polls.update(vote.pollId, $inc: votesCount: 1);
Votes.insert(vote);
DDP 的运行方式位于文档的顶层,因此这意味着如果投票是投票的属性,则每次在投票中创建投票时,服务器都会发送该投票的整个更新投票列表发送到每个连接的客户端。
【讨论】:
谢谢。我会买发现流星的书,让自己对流星更舒服!【参考方案2】:对数据进行非规范化肯定有利有弊。因此,总结一下这两个选项 - 您可以创建一个单独的投票集合,或者您只是将投票包含在您的投票集合中。
通过单独的集合,您肯定会获得一些好处。当使用 #each 模板块迭代游标 (Votes.find(pollId: pollId)) 时,它的性能非常好 - 如果你正在迭代一个数组或对象集合,那就不是这样了。
您决定将投票作为对象包含在投票中的一个问题是,DDP 仅在文档的***别属性上运行。这意味着每次添加投票时,都会发送整个“投票”对象。
使用单独的集合,您还可以获得更好的发布/订阅控制的好处。
话虽如此,如果您只使用一个单独的集合,您将不得不做一些烦人的事情(如您所提到的)只是为了获得票数,即您必须将所有票发布给客户端只是为了数一数。
许多开发人员选择混合选项,即拥有一个单独的 Votes 集合,同时在 Polls 集合中嵌入一些关于投票的重要属性(例如计数)。这也变得有点烦人,这意味着每次有人投票时您都必须更新两个不同的集合。在这种情况下,我会说你几乎是在正确的轨道上。
【讨论】:
谢谢。与往常一样,在进入一项新技术时,我对最佳实践有点不确定。但似乎,通常情况下,没有灵丹妙药,一切都有其优点和缺点。您描述的混合方法是 SQL 数据库中非常常见的做法。我试图遵循 NoSQL 文档数据库的理念,但是当我尝试在一些现实世界的用例中使用它们时,尤其是与 Meteor 结合使用时,它们很容易让我头疼并让我求助于我的旧做法。我很高兴听到这不是问题。 你会发现 Meteor 最好和最坏的事情之一就是有很多不同的路径可以达到相同的结果。快乐的流星!以上是关于如何为 Meteor 构建 mongodb的主要内容,如果未能解决你的问题,请参考以下文章