简体   繁体   中英

Sort a result according to the size of an array with Mongoose

I'm using MongoDB (mongoose), and I'm looking to sort the elements by Array size (descending order). I've tried a lot of things, but I don't understand how it works. I'd like to avoid sorting the results manually (I mean with the JS), I'd rather have MongoDB do it. Can you help me please?

Here is my code:

users = await userModel.find({ UserStatus: "Success" })
  .sort({ "Progression.Room.RoomActorLikes": { "length": -1 } })
  .skip((request.pageindex) * request.pagesize)
  .limit(request.pagesize);

Here is an example that could be the first result:

The second would be:

And so on...

Thank you in advance for your answer!

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:

  1. $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 )

  2. $addFields -> Create new field len that will contain the number of array elements in document array to be easy to sort later.

  3. $sort -> Sort in descending order ithe documents based on array counts.

  4. $skip the number of documents to display as part of your paging action.

  5. $limit the number of ducuments to display as part of your paging action.

  6. $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 )

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM