我应该使用 AutoValue 来存储集合的聚合值吗?

Should I use AutoValue to store aggregated values of a collection?

我有一个 Comments 集合和一个 Page 集合。评论属于页面。用户可以对评论进行投票,我想显示属于页面的评论的所有投票的总和。这样做的好方法是什么?

我正在考虑将总和作为自动值保存在页面集合中。有没有办法偶尔触发自动值的重新计算?我不需要实时更新总和,每 5 分钟一次就足够了。

或者这是个坏主意?在模板中使用 ReactiveVar 进行计算或其他方法会更好吗?

编辑: 设置并没有什么特别之处,真的。只是一个带有数字 'votes' 属性的评论集合和一个带有数字自动值 'score' 的页面集合,应该计算选票。 页数:

Collections.Pages = new Mongo.Collection("pages");

var PageSchema = new SimpleSchema({
    name: {
        type: String,
        min: 1
    },
    score: {
        type: Number,
        autoValue: function (doc) {
                var maxValue = 1;
                Collections.Comments.find({ pageId: doc.pageId }).map(function(mapDoc){
                    maxValue += mapDoc.votes;
                });
                return maxValue;
        }
    },

评论:

Collections.Comments = new Mongo.Collection("comments");

var CommentSchema = new SimpleSchema({
    pageId: {
        type: String
    },
    name: {
        type: String,
        optional: true
    },
    votes: {
        type: Number,
        label: 'Total Votes',
        defaultValue: 0
    },

也许 periodic/timed 重新计算的另一种方法可能是简单地重新计算一个集合中的值以响应另一个集合中的更改。您说您 不需要 实时,但我想您不会介意它是实时的。

我遇到了类似的挑战并使用了 Meteor Collection Hooks 包(参见 https://github.com/matb33/meteor-collection-hooks)。

示例:

Collection.comments.after.update(function(userId, doc) { // make update to aggregated value in Collections.pages });

我做了类似的事情:我有带评论的新闻项目,我想跟踪每个新闻项目的评论数量 w/o 必须发布所有评论。

我选择给新闻一个 commentCount 字段。我有添加和删除评论的方法,作为该处理的一部分,我查找了相关的新闻项目并增加或减少了它的计数。

您在架构解决方案中发现的是没有明确的方法来触发 autoValue。 (这是 autoValue 的一个有趣用法,顺便说一句,我必须记住这一点以备将来使用)。

所以我认为您还有这些选择:

  1. 创建 upvote/downvote 投票方法。在方法处理程序中,计算总票数并将更新后的值与 post 一起存储。这类似于我对 News/Comments.

  2. 所做的
  3. 正如 David 所建议的那样,使用收集挂钩来执行类似于 #1 的操作。虽然我确实使用收集钩子,但通常是当我对我想做的事情没有明确的钩子时,它更像是一个包罗万象的东西,或者处理一些我不完全控制的东西。

  4. 在发布时注意它。当您发布页面时,还要查看投票计数并简单地动态添加到发布对象。请注意,这不会在投票发生变化时重新发布页面,因此您会失去这种反应性;您确实表示您可以定期更新。

更新会有点棘手,因为您将不得不强制发布者再次 运行。例如通过取消订阅和重新订阅。

在这 3 个中,根据我对你的问题的理解,我喜欢它们的顺序。 #3 感觉最不可行,但我提到它以防它适合你正在做的其他事情。