Sort a result according to the size of an array with Mongoose
Solution 1:
What about this:
db.collection.aggregate([ { $addFields:{ len:{$size:"$room.RoomActorLikes"}}} , {$sort:{len:-1}} ,{$skip: skip},
{$limit: limit} ])
Detailed example:
db.collection.aggregate([
{
$match: {
UserStatus: "Success"
}
},
{
$addFields: {
len: {
$size: "$room.roomActorLikes"
}
}
},
{
$sort: {
len: -1
}
},
{
$skip: 1
},
{
$limit: 3
},
{
$project: {
len: 0
}
}
])
explained:
-
$match -> Here reduce the amount of documents down to the ones that are with UserStatus-> Success in $match stage or if there is more conditions better so the amount of documents that need to be processed in later stages to be smaller. ( Best is to have index on this field so if you have too many documents this to reduce the processing as much as possible )
-
$addFields -> Create new field len that will contain the number of array elements in document array to be easy to sort later.
-
$sort -> Sort in descending order ithe documents based on array counts.
-
$skip the number of documents to display as part of your paging action.
-
$limit the number of ducuments to display as part of your paging action.
-
$project to remove the len field if you dont need in the final output ( this is optional since you may not consider it from the app side )
playground
Abit more safer option $addFields->$size , preventing error messages in case of missing RoomActorlikes or missing room field from the main document:
{
$addFields: {
len: {
$size: {
$cond: {
if: {
$eq: [
{
$type: "$room.roomActorLikes"
},
"missing"
]
},
then: [],
else: "$room.roomActorLikes"
}
}
}
}
}
playground safe option ( checking if RoomActorLikes exist )