Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to define a sort function in Mongoose

I'm developing a small NodeJS web app using Mongoose to access my MongoDB database. A simplified schema of my collection is given below:

var MySchema = mongoose.Schema({                                 
    content:   { type: String },     
    location:  {                                                        
         lat:      { type: Number },                       
         lng:      { type: Number },                                              
    },
    modifierValue:  { type: Number }     
});

Unfortunately, I'm not able to sort the retrieved data from the server the way it is more convenient for me. I wish to sort my results according to their distance from a given position (location) but taking into account a modifier function with a modifierValue that is also considered as an input.

What I intend to do is written below. However, this sort of sort functionality seems to not exist.

MySchema.find({})
        .sort( modifierFunction(location,this.location,this.modifierValue) )
        .limit(20)       // I only want the 20 "closest" documents
        .exec(callback)

The mondifierFunction returns a Double.

So far, I've studied the possibility of using mongoose's $near function, but this doesn't seem to sort, not allow for a modifier function.

Since I'm fairly new to node.js and mongoose, I may be taking a completely wrong approach to my problem, so I'm open to complete redesigns of my programming logic.

Thank you in advance,

like image 880
pupo162 Avatar asked Jan 03 '17 22:01

pupo162


People also ask

How do I sort in MongoDB?

To sort documents in MongoDB, you need to use sort() method. The method accepts a document containing a list of fields along with their sorting order. To specify sorting order 1 and -1 are used. 1 is used for ascending order while -1 is used for descending order.

How do I sort in node JS?

Use the sort() method to sort the result in ascending or descending order. The sort() method takes one parameter, an object defining the sorting order.

What is skip in mongoose?

In Mongoose, the skip() method is used to specify the number of documents to skip. When a query is made and the query result is returned, the skip() method will skip the first n documents specified and return the remaining.

How do you use Mongoose Paginate?

Try using mongoose function for pagination. Limit is the number of records per page and number of the page. Show activity on this post. var paginate = 20; var page = pageNumber; MySchema.


1 Answers

You might have found an answer to this already given the question date, but I'll answer anyway.

For more advanced sorting algorithms you can do the sorting in the exec callback. For example

MySchema.find({})
  .limit(20)
  .exec(function(err, instances) {
      let sorted = mySort(instances); // Sorting here

      // Boilerplate output that has nothing to do with the sorting.
      let response = { };

      if (err) {
          response = handleError(err);
      } else {
          response.status = HttpStatus.OK;
          response.message = sorted;
      }

      res.status(response.status).json(response.message);
  })

mySort() has the found array from the query execution as input and the sorted array as output. It could for instance be something like this

function mySort (array) {
  array.sort(function (a, b) {
    let distanceA = Math.sqrt(a.location.lat**2 + a.location.lng**2);
    let distanceB = Math.sqrt(b.location.lat**2 + b.location.lng**2);

    if (distanceA < distanceB) {
      return -1;
    } else if (distanceA > distanceB) {
      return 1;
    } else {
      return 0;
    }
  })

  return array;
}

This sorting algorithm is just an illustration of how sorting could be done. You would of course have to write the proper algorithm yourself. Remember that the result of the query is an array that you can manipulate as you want. array.sort() is your friend. You can information about it here.

like image 138
Mika Sundland Avatar answered Oct 01 '22 03:10

Mika Sundland