2

I need to keep track of a counter of a collection with a huge number of documents that's constantly being updated. (Think a giant list of logs). What I don't want to do is to have the server send me a list of 250k documents. I just want to see a counter rising.

I found a very similar question here, and I've also looked into the .observeChanges() in the docs but once again, it seems that .observe() as well as .observeChanges() actually return the whole set before tracking what's been added, changed or deleted.

In the above example, the "added" function will fire once per every document returned to increment a counter.

This is unacceptable with a large set - I only want to keep track of a change in the count as I understand .count() bypasses the fetching of the entire set of documents. The former example involves counting only documents related to a room, which isn't something I want (or was able to reproduce and get working, for that matter)

I've gotta be missing something simple, I've been stumped for hours.

Would really appreciate any feedback.

Community
  • 1
  • 1
dsp_099
  • 5,801
  • 17
  • 72
  • 128
  • MongoDb doesn't have this feature. You'll need to build the count artificially, or switch platforms. The closest you can get I believe is using a capped collection, but it returns more than a count. http://docs.mongodb.org/manual/tutorial/create-tailable-cursor/ – WiredPrairie Oct 06 '13 at 11:38

2 Answers2

1

You could accomplish this with the meteor-streams smart package by Arunoda. It lets you do pub/sub without needing the database, so one thing you could send over is a reactive number, for instance.

Alternatively, and this is slightly more hacky but useful if you've got a number of things you need to count or something similar, you could have a separate "Statistics" collection (name it whatever) with a document containing that count.

BenjaminRH
  • 11,974
  • 7
  • 49
  • 76
1

There is an example in the documentation about this use case. I've modified it to your particular question:

// server: publish the current size of a collection
Meteor.publish("nbLogs", function () {
  var self = this;
  var count = 0;
  var initializing = true;
  var handle = Messages.find({}).observeChanges({
    added: function (id) {
      count++;
      if (!initializing)
        self.changed("counts", roomId, {nbLogs: count});
    },
    removed: function (id) {
      count--;
      self.changed("counts", roomId, {nbLogs: count});
    }
    // don't care about moved or changed
  });

  // Observe only returns after the initial added callbacks have
  // run.  Now return an initial value and mark the subscription
  // as ready.
  initializing = false;
  self.added("counts", roomId, {nbLogs: count});
  self.ready();

  // Stop observing the cursor when client unsubs.
  // Stopping a subscription automatically takes
  // care of sending the client any removed messages.
  self.onStop(function () {
    handle.stop();
  });
});

// client: declare collection to hold count object
Counts = new Meteor.Collection("counts");

// client: subscribe to the count for the current room
Meteor.subscribe("nbLogs");

// client: use the new collection
Deps.autorun(function() {
  console.log("nbLogs: " + Counts.findOne().nbLogs);
});

There might be some higher level ways to do this in the future.

mquandalle
  • 2,600
  • 20
  • 24