Reputation: 598
Is there a way to sort by a given array?
something like this:
const somes = await SomeModel.find({}).sort({'_id': {'$in': [ObjectId('sdasdsd), ObjectId('sdasdsd), ObjectId('sdasdsd)]}}).exec()
What i looking for is a way to get a solution, to get all document of the collection and sort by if the document's _id match with one of the given array.
An example:
we have albums collection and songs collection. In albums collection we store the ids of the songs that belongs to the albums.
I want to get the songs, but if the song is in the album take them front of the array.
I solved this as follow, but its looks a bit hacky:
const songs = await SongMode.find({}).skipe(limit * page).limit(limit).exec();
const album = await AlbumModel.findById(id).exec();
if(album) {
songArr = album.songs.slice(limit * page);
for(let song of album.songs) {
songs.unshift(song);
songs.pop();
}
}
Upvotes: 0
Views: 134
Reputation: 7220
This cannot be accomplished using an ordinary .find().sort()
. Instead, you will need to use the MongoDB aggregation pipeline (.aggregate()
). Specifically, you will need to do the following:
$project
ion such that if the _id
is $in
the array, your new sort_field
is given the value 1
, otherwise it's given a value of 0
.$sort
such that you're doing a descending sort on the new sort_field
.If you're using MongoDB version 3.4 or greater, then this is easy because of the $addFields
operator:
const your_array_of_ids = [
ObjectId('objectid1'),
ObjectId('objectid2'),
ObjectId('objectid3')
];
SomeModel.aggregate([
{ '$addFields': {
'sort_field': { '$cond': {
'if': { '$in': [ '$_id', your_array_of_ids ] },
'then': 1,
'else': 0
}}
}},
{ '$sort': {
'sort_field': -1
}}
]);
If you're using an older version of MongoDB, then the solution is similar, but instead of $addFields
you will be using $project
. Additionally, you will need to explicitly include all of the other fields you want included, otherwise they will be excluded from the results.
Upvotes: 1