Reputation: 63727
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
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