I'm developing a web app in nodejs connected to mongodb via mongo native connector.
In one of my js files, I have a generic method to invoke a "find" or "findOne" operation to retrieve whatever I need from a mongodb collection, like this:
It works fine for me.
But now, I need to sort the results, and as far as I know, Mongodb use the "sort" method to achieve this.
collection.ensureIndex(indexedFields, function(error, indexName) {
if (error) {
callback(error);
} else {
var operation = (params.options.one) ? collection.findOne : collection.find;
operation.call(collection, params.selector, params.fields, params.options,
function(error, result){
if (error) {
...
} else {
...
}
}
);
}
});
In an simple query, this should be like this: For example:
collection.find().sort({field : 1}),
I don't know how to call "sort" method, doing it im my generic way.
Any ideas?
Thanks.
Have you looked into mongojs (https://github.com/gett/mongojs) ? I use this for my node apps and it works nicely (I also use expressjs). You can do a simple find and sort by with the following syntax:
db.test.find().sort({name:1}, function(error, tuples) { console.log(tuples) });
Can't you just do the same thing to the output of your call?:
operation.call(collection, params.selector, params.fields, params.options,
function(error, result){
...
}
).sort({field: 1});
If the sort can only be applied to the results of find
and not findOne
, then it's a bit more complicated:
var operation = (params.options.one) ? collection.findOne : function() {
var findResults = collection.find.apply(this, [].slice.call(arguments));
return findResults.sort({field: 1});
};
(That last is entirely untested, of course, but looks like it should be close.)
It should be almost like Scott said.
The first method does not work, cause sort is called by an undefined object. I think it takes sense, because there's a callback which is performed first.. The second method is almost what i need, but not working, once again, findResults.sort returns an undefined.
I finally did something more easy, what it seems to succeed, but... there's still something missing:
operation.call(collection, params.selector, params.fields, params.options,
function(error, result){
if (err) ....
else results.sort({field:1}, callback(err, sortedResults))
}
well, It pauses at "results.sort", and it remains waiting... I don't know what. Looking at mongodb console, there's no query launched. In the other hand, callback exists as a function, but not called...
Then, I tried to do this in another way;
var sortedResults = results.sort({field:1};
callback(err, sortedResults)
In this case, the execution goes on, but, it returns unsorted results.
Any other ideas? It has to be there....
thanks
I've found the solution.
It seems that "toArray" was missing, otherwise does not work.
operation.call(collection, params.selector, params.fields, params.options, function(error, result) {
if (error) {
callback(error);
} else {
result.sort(params.sort).toArray(function(error, items) {
...
}
}
I Hope it will be helpful
using cursors is the best solution because the sorting is processeced in mongodb engine
var grades = db.collection('data');
var cursor = grades.find();
// cursor.skip(1);
// cursor.limit(4);
// cursor.sort(['State', 1]);
cursor.sort( [['Temperature', 'desc'],['State','asc']] );
//var options = { 'skip' : 1,
// 'limit' : 4,
// 'sort' : [['grade', 1], ['student', -1]] };
//var cursor = grades.find({}, {}, options);
cursor.each(function(err, doc) {
if(err) throw err;
if(doc == null) {
return db.close();
}
console.dir(doc);
});