Sorting and reactive aggregation


#1

I’m trying to aggregate items created and voted on by users. I have tried to implement the reactive aggregation package, but for whatever reason, I couldn’t get it to work. Therefore, I tried a different approach, which involved set an aggregation value whenever a user votes on an item. It adds the votes of an item and divides it by the amount of days that have passed. I need the items to be sorted such that the newer items with more votes appear the the top, while the older item with less votes lowers over time.

Even with the approach that I have implemented in the application, there’s two issues with it. When a user votes on an item, it bounces all over the place. I tried to stop this reactivity from happening by applying the following to it, but it still has the same issue:

  return Tracker.nonreactive(function () {
    return items;
  })

Furthermore, the items are only updated when a user votes on them. I’m not sure what would be the best approach to this issue.


#2

I still can’t implement reactive aggregation. Nothing is going into the local collection, so I don’t understand what’s the problem with the code. I have tried the following on the server side:

  Meteor.publish('aggregateItems', function aggItemsPublication(userArea){
    var regexArea = new RegExp(["^", userArea, "$"].join(""), "i");
    ReactiveAggregate(this, Items,
      [
        {$match: {area: regexArea}},
        {$sort: {created: -1, count: 1}}
      ],
        {clientCollection: 'aggItems'}
    );
  });

Then added the following on the client side (with viewmodel):

aggItems = new Mongo.Collection(null);

Template.discussions.viewmodel({
  autorun() {
    Meteor.subscribe('aggregateItems', userArea());
  },
  items() {
    // add search to items area from search properties
    var items = aggItems.find({text: this.searchRegEx()});
    return items;
  }
});

And for the front end:

{{#each items}}
   {{> item}}
{{/each}}

#3

I figured it out. The local collection isn’t supposed to be null, but as such:

  Meteor.publish('aggregateItems', function aggItemsPublication(userArea){
    var regexArea = new RegExp(["^", userArea, "$"].join(""), "i");
    ReactiveAggregate(this, Items,
      [
        {$match: {area: regexArea}},
        {$sort: {created: -1, count: 1}}
      ],
        {clientCollection: 'aggregation'}
    );
  });

And the following for the client side:

aggItems = new Mongo.Collection('aggregation');