Skip to content

Sorting during population of a path in a subdocument attaches the populated document to the wrong subdocument #2202

@paton

Description

@paton

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);
      }
    );
  });
});

Metadata

Metadata

Assignees

No one assigned

    Labels

    confirmed-bugWe've confirmed this is a bug in Mongoose and will fix it.

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions