Is there a faster way to count documents?


#1

Currently, we’re using a method described in the bulletproofmeteor course:
A Better Way to Count Documents

It’s about counting documents on the server side and publishing counters to the client.
I’m wondering if it’s possible to minimize the delay in order to provide a better user experience.
The delay is happening only after the first screen loading because of subsmanagers that cache these subscription. The loading time depends on the number of documents that need to be counted.

Here’s a visualization of this issue (the application is deployed):


#2

I’ve learned that the best way to have access to counts immediately in Meteor is just store them inside a collection. If it’s something simple you can just recalculate the count and store it on every insert/update/delete action. If it’s more complicated/time-consuming you can put it in a job which will either run periodically or when triggered by a insert/update/delete action.


#3

https://atmospherejs.com/tmeasday/publish-counts


#4

I use: https://atmospherejs.com/natestrauser/publish-performant-counts


#5

https://atmospherejs.com/natestrauser/publish-performant-counts uses the same bulletproof meteor counting method

If your counts are not user specific (eg count all docs vs count all of the current user’s docs), you can also have them be ‘server scoped’ by defining them outside of the publish function. Done this way, the count is created on server startup and is immediately ready to be published without counting again. If you create the counter within the publish function, it will be initialized and only do the first count after you subscribe.

var counter = new Counter('countCollection', Collection.find({}));

Meteor.publish('countPublish', function() {
  return counter;
});

It looks like your counts are just dependent on the ‘company’, so you could do something like:

var counters = {};
Companies.find().forEach(function(company){
 counters[company.name] = new Counter('countCollection'+company.name, Collection.find({companyId:company._id}));
});
//this is ok if companies aren't added/changed, probably should be done with observeChanges to be fully reactive


Meteor.publish('countPublish', function(companyName) {
  return counters[companyName];
});

That should give you counts returned very quickly from your subscribe calls.


#6

Has anyone tested both tsmeasday’s public-counts vs. natestrauser’s publish-performant-counts and come up with a winner?