BumbleGee
BumbleGee

Reputation: 2031

How to sort array of embedded documents via Mongoose query?

I'm building a node.js application with Mongoose and have a problem related to sorting embedded documents. Here's the schema I use:

var locationSchema = new Schema({
    lat: { type: String, required: true },
    lon: { type: String, required: true },
    time: { type: Date, required: true },
    acc: { type: String }
})

var locationsSchema = new Schema({
    userId: { type: ObjectId },
    source: { type: ObjectId, required: true },
    locations: [ locationSchema ]
});

I'd like to output the locations embedded in the userLocations documented sorted by their time attribute. I currently do the sorting in JavaScript after I retrieved the data from MongoDb like so:

function locationsDescendingTimeOrder(loc1, loc2) {
   return loc2.time.getTime() - loc1.time.getTime()
}

LocationsModel.findOne({ userId: theUserId }, function(err, userLocations) { 
   userLocations.locations.sort(locationsDescendingTimeOrder).forEach(function(location) {
      console.log('location: ' + location.time);
   }
});

I did read about the sorting API provided by Mongoose but I couldn't figure out if it can be used for sorting arrays of embedded documents and if yes, if it is a sensible approach and how to apply it to this problem. Can anyone help me out here, please?

Thanks in advance and cheers, Georg

Upvotes: 4

Views: 6088

Answers (2)

Jayanga Jayathilake
Jayanga Jayathilake

Reputation: 699

This also can be done using mongoose sort API as well.

LocationsModel.findOne({ userId: theUserId })
//    .sort({ "locations.time": "desc" }) // option 1
    .sort("-locations.time")              // option 2
    .exec((err, result) => {
        // compute fetched data
    })

Sort by field in nested array with Mongoose.js

More methods are mentioned in this answer as well

Sorting Options in mogoose

Mongoose Sort API

Upvotes: 0

glortho
glortho

Reputation: 13200

You're doing it the right way, Georg. Your other options are either to sort locations by time upon embedding in the first place, or going the more traditional non-embedded route (or minimally embedded route so that you may be embedding an array of ids or something but you're actually querying the locations separately).

Upvotes: 4

Related Questions