Moongose: sort by math and search by multiple values in string array

Hello fellow SO users,

I have run into some advanced Mongoose querying which i simply can't figure out from the docs.

First off, i'd like to sort by some math. Basicly i would like to be able to sort by a price difference on two objects. I have "price" and "oldprice", which contains basic number values. I would then like to substract them and sort by the highest discount. So in SQL i would be something like

ORDER BY (oldprice - price)

Another problem i've run into is filtering a string array by a string array.

So basicly i have a "Pants" model, with a [size] object (string array), which contains multiple sizes. Now i want to be able to search the db by multiple user selected sizes, and find ALL pants which contains ONE of selected sizes.

I've tried doing:

Pants.find({
  name: new RegExp(search, 'ig'),
  sizes: {
    $in: [selectedSizes]
  }
}).skip(skip).limit(limit).sort(sort).execFind(function(err, pants) {
  return res.send(pants);
});

Which works fine if one value is in the "selectedSizes", but fails with multiple values.

Hope someone have some ideas ;-)


Pants model:

var PantsSchema;
PantsSchema = new mongoose.Schema({
  supplier: {
    type: String
  },
  manufacturer: {
    type: String
  },
  web: {
    type: String
  },
  name: {
    type: String
  },
  link: {
    type: String,
    required: true,
    unique: true
  },
  image: {
    type: String
  },
  sizes: {
    type: [String]
  },
  price: {
    type: Number
  },
  oldprice: {
    type: Number
  },
  added: {
    type: Date,
    "default": Date.now
  },
  updated: {
    type: Date
  }
});

For the order by question, you'll need to create a field in Mongo that stores the value of oldPrice - price since you can only sort by a field (and you'll want to index this field).

Then you just add a sort expression to your mongoose call:

.sort('priceDifference', 1);  // 1 or -1 depending on ascending or descending

For the second question, you'll need to create $or expressions, one for each size that you are looking for. I think it would look something like this:

.find( { $or : [ { sizes : { $in: ['m'] } }, { sizes : {$in: ['l'] } } ] } )