Pratik Agarwal
Pratik Agarwal

Reputation: 348

Getting last N entries from collection | Pagination problem using Mongoose

I've made notifications collection and in it I put notification as per the below schema:

{
  userid: mongoose.Schema.Types.ObjectId  // the user who generated this notification
  customReceivers: [String],
  time: Number, // new Date().getTime();
... other fields
}

Im trying to display notifications by pagination and sorting but I get a specific order. Like first N notifications will point from 1h ago to 2 days ago then another pagination will again show 5h ago to 26 days ago and so on.

Im using this query to find:

notificationModel.find({userid: {$in: followingList}}.sort({time: -1}).skip(pageNo * entriesPerPage).limit(entriesPerPage).then(...
followingList = [mongoose.ObjectId("60bb75c3eb840300226bd3a8"),
mongoose.ObjectId("60bb77eeeb840300226bd3ac"), ...]

I've tried using sort({$natural: 1}) it didnt work

As by default the entries are saved in ascending order of time, I just need to take last N entries and reverse the array. but the order I get is different. Thanks for help

Upvotes: 1

Views: 181

Answers (2)

Pratik Agarwal
Pratik Agarwal

Reputation: 348

Found the solution. Problem is in the statement:

notificationModel.find({userid: {$in: followingList}}.sort({time: -1}).skip(pageNo * entriesPerPage).limit(entriesPerPage).then(...

$in doesn't guarantee the order of the the data (be it 1 to 1 or 1 to many relations), and hence it needs to be checked by the conditions put using $cond and $eq or what I did:

  1. get all the notification IDs created by people user follows
  2. get details and flags like seenByUser or any other details in aggregate and there give up the condition of skip and limit
notifications = await notificationModel.aggregate([
            {
                $match: { _id: { $in: notificationIDs } }, // Id got from find() previously
                
            },
            {$sort: {"time": -1}},
            { $skip: (pageNo - 1) * entriesPerPage },
            { $limit: entriesPerPage },
}

Upvotes: 0

Ammar
Ammar

Reputation: 272

Maybe sorting through _id can help if sorting through time property is not working.

notificationModel.find({userid: {$in: followingList}}.sort({_id: -1}).skip(pageNo * entriesPerPage).limit(entriesPerPage).then(...

Upvotes: 1

Related Questions