mongoose: Sorting during population of a path in a subdocument attaches the populated document to the wrong subdocument
Sorting of populated documents within subdocuments results in the populated document being attached to the wrong subdocument.
Mongoose: 3.8.13
Mongodb: 2.6.3
Check out the differing quantity fields when sorting the populated product field ascending vs descending…
// Ascending sorting of populated product by "name"
{
  suborders: [
    { _id: '...14cb', product: { name: 'Apple' }, quantity: 1 }  // Correct quantity
    { _id: '...14ca', product: { name: 'Banana' }, quantity: 2 }  // Correct quantity
  ]
}
// Descending sorting of populated product by "name"
{
  suborders: [
    { _id: '...14cb', product: { name: 'Banana' }, quantity: 1 }  // INCORRECT quantity
    { _id: '...14ca', product: { name: 'Apple' }, quantity: 2 }  // INCORRECT quantity
  ]
}
Ascending sort: 1 apple, 2 bananas Descending sort: 2 apples, 1 banana
Apple should always be attached to the subdocument with _id ending in ‘14cb’, but in the descending sort it’s attached to the suborder with _id ending in ‘14ca’.
Failing test code below…
// SETUP SCHEMA 
var ProductSchema = new mongoose.Schema({ name: String });
mongoose.model('Product', ProductSchema);
var SuborderSchema = new mongoose.Schema({
  product: {
    type: mongoose.Schema.Types.ObjectId,
    ref: 'Product'
  },
  quantity: Number
});
var OrderSchema = new mongoose.Schema({ 
  suborders: [SuborderSchema] 
});
mongoose.model('Order', OrderSchema);
//// FAILING TEST
var Order = mongoose.model('Order');
var Product = mongoose.model('Product');
// Create 2 products
Product.create([
  { name: 'Apple' }, 
  { name: 'Banana' }
], function(err, apple, banana) {
  // Create order with suborders
  Order.create({
    suborders: [
      {
        product: apple._id,
        quantity: 1
      }, {
        product: banana._id,
        quantity: 2
      }
    ]
  }, function(err, order) {
    // Populate with ascending sort 
    Order.findById(order._id)
      .populate({
        path: 'suborders.product',
        options: { sort: 'name' } // ASCENDING SORT
      }).exec(function(err, order) {
        console.log('Ascending sort');
        console.log(order.suborders);
      }
    );
    // Populate with descending sort
    Order.findById(order._id)
      .populate({
        path: 'suborders.product',
        options: { sort: '-name' } // DESCENDING SORT
      }).exec(function(err, order) {
        console.log('Descending sort');
        console.log(order.suborders);
      }
    );
  });
});
About this issue
- Original URL
 - State: closed
 - Created 10 years ago
 - Reactions: 3
 - Comments: 24 (1 by maintainers)
 
Links to this issue
Commits related to this issue
- docs(faq): add comments re: #2202 — committed to Automattic/mongoose by vkarpov15 8 years ago
 - test(populate): repro #2202 — committed to Automattic/mongoose by vkarpov15 7 years ago
 - fix(populate): return an error if sorting underneath a doc array Fix #2202 — committed to Automattic/mongoose by vkarpov15 7 years ago
 - Don't sort populated Mongo documents Sorting populated documents is not possible at the moment due bug in Mongoose: http://mongoosejs.com/docs/faq.html#populate_sort_order https://github.com/Automat... — committed to Trustroots/trustroots by simison 7 years ago
 
Same on 3.8.25 with node v0.10.37 and MongoDB 3.0.1
Test:
Could you provide an example @mrm8488? I’ve the same problem, I had to sort with JS.
I’ve also a problem with
limit, it works only on doc not on arrays 😕Thanks all!
@paton made it return an error. Very tricky to come up with a way to do this since populate is not architected to handle sort, limit, and skip underneath document arrays. Reworking the current architecture will be a substantial project that will take time to scope out.
Yeah I’m going to put this in the FAQ. This is a longstanding bug in mongoose that’s tricky to fix. This is why you should be extra careful in testing your code 😃