meteormeteor-collection2

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


I have a Comments collection and a Page collection. Comments belong to pages. Users can upvote the comments, and I want to display the aggregated sum of all the votes of the comments belonging to a page. What would be a good way to do this?

I was thinking of keeping the sum as an AutoValue inside the page collection. Would there be a way to occasionally trigger a recalculation of the AutoValue? I don't need the sum to be updated realtime, once every 5 minutes would suffice.

Or is this a bad idea? Would it be better to use a ReactiveVar in the template to do the calculation, or something else?

Edit: There's not much special about the setup, really. Simply a comment collection with a numeric 'votes' attribute and a pages collection with a numeric autovalue 'score' that should count the votes. The pages:

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;
        }
    },

The comments:

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
    },

Solution

  • Maybe an alternative approach to periodic/timed recalculations might be to simply recalculate the value in one collection in response to a change in the other collection. You said you don't need realtime, but I don't imagine you'd mind if it was realtime.

    I had a similar challenge and used the Meteor Collection Hooks package (see https://github.com/matb33/meteor-collection-hooks).

    Example:

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