8

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.

freakish
  • 54,167
  • 9
  • 132
  • 169
larrytron
  • 689
  • 4
  • 11
  • 26

6 Answers6

7

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) });
Alex Roe
  • 586
  • 5
  • 11
1

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.)

Scott Sauyet
  • 49,207
  • 4
  • 49
  • 103
1

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);
});
mar1
  • 193
  • 1
  • 3
1

I have an articles model where I want to search by category and get the latest article based on the created date and this is how I do it

const query = {category: "category1"};
Articles.find(query, callback).sort({created_date: -1});
Nikhil Das Nomula
  • 1,863
  • 5
  • 31
  • 50
0

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

larrytron
  • 689
  • 4
  • 11
  • 26
0

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

larrytron
  • 689
  • 4
  • 11
  • 26