When using MongoDB\'s $in clause, does the order of the returned documents always correspond to the order of the array argument?
If you don't want to use aggregate
, another solution is to use find
and then sort the doc results client-side using array#sort:
If the $in
values are primitive types like numbers you can use an approach like:
var ids = [4, 2, 8, 1, 9, 3, 5, 6];
MyModel.find({ _id: { $in: ids } }).exec(function(err, docs) {
docs.sort(function(a, b) {
// Sort docs by the order of their _id values in ids.
return ids.indexOf(a._id) - ids.indexOf(b._id);
});
});
If the $in
values are non-primitive types like ObjectId
s, another approach is required as indexOf
compares by reference in that case.
If you're using Node.js 4.x+, you can use Array#findIndex and ObjectID#equals to handle this by changing the sort
function to:
docs.sort((a, b) => ids.findIndex(id => a._id.equals(id)) -
ids.findIndex(id => b._id.equals(id)));
Or with any Node.js version, with underscore/lodash's findIndex:
docs.sort(function (a, b) {
return _.findIndex(ids, function (id) { return a._id.equals(id); }) -
_.findIndex(ids, function (id) { return b._id.equals(id); });
});