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 😃