Nyxynyx
Nyxynyx

Reputation: 63727

Sorting documents in Meteor.js collection causes browser to crash

I am trying to retrieve the newest document from a collection which has a timestamp field. However when using the sort specifier with either find() or findOne(), the browser becomes very unresponsive, CPU usage shoots up and occasionally crashes.

The sorted result returned is also not sorted correctly when compared to a direct query on mongodb using db.fruits.find().sort({timestamp: -1}). An example of a value in the timestamp field is 2013-11-28 21:48:02. There are 5000+ documents in db.fruits with an index on timestamp.

Any ideas what went wrong? I'm using Meteor v0.6.6.3 on Mac OSX Chrome.

Case 1A: Responsive

Template.fruits.fruit = function() {
    var fruit = Fruits.findOne({});
    return fruit;
}

<template name="fruits">
    <div>{{fruit.price}}</div>
</template>

Case 1B: Unresponsive

Template.fruits.fruit = function() {
    var fruit = Fruits.findOne({},{sort:{timestamp: -1}});
    return fruit;
}

Case 2A: Responsive

Template.fruits.fruit = function() {
    var fruit = Fruits.find({}, {limit :1});
    return fruit;
}

<template name="fruits">
    {{#each fruit}}
    <div>{{price}}</div>
    {{/each}}
</template>

Case 2B: Unresponsive

Template.fruits.fruit = function() {
    var ticks = Ticks.find({}, {sort:{timestamp: -1}, limit :1});
    return fruit;
}

Publishing only the newest 10 fruits

Suggested by David Weldon

Meteor.publish('fruits', function(userId) {
    return Fruits.find({}, {sort:{timestamp: -1}, limit: 10});
});

It stops crashing the browser, and also returns the correct result!

Upvotes: 2

Views: 934

Answers (1)

David Weldon
David Weldon

Reputation: 64342

I'm uncertain if meteor is continually trying to sort the documents as they are sent to the client (restarting every time a new one is sent), or if it blocks on the full result set before executing the sort. Either way, I strongly recommend against syncing thousands of documents to the client. As you illustrated in your example, it's resource intensive in both network and CPU.

Your goal should be to sync small subsets of the database on an as-needed basis. If you need to operate on a large dataset, I'd recommend using a method call (and possibly caching the results on the server).

Upvotes: 1

Related Questions