Reputation: 1647
I am trying to do pagination with Mongo using skip
and limit
.
I want to get the page records sorted by register_time
. In the database, the records are sorted by index and not by register_time
.
How can I make multiple pages of records (multiple skips) follow the same register_time
order ?
db.collection.aggregate(
[ { "$project" : { "os" : "$os",
"register_time" : "$register_time",
"channel" : "$channel",
"event" : "$event",
"user_id" : "$user_id" } },
{ "$match" : { "register_time" :
{ "$gt" : ISODate("2016-06-23T00:00:00Z"),
"$lt" : ISODate("2050-06-25T23:59:00Z") },
"event" : "Register_with_number",
"channel" : "001" } },
{ "$group" : { "_id" :
{ "register_time" : "$register_time",
"user_id" : "$user_id",
"os" : "$os",
"channel" : "$channel" },
"count" : { "$sum" : 1 } } },
{"$skip":4},
{"$limit":10},
{ "$sort" : {"_id.register_time" : -1 } } ])
And here is the skip
result
{ "_id" : { "register_time" : ISODate("2016-06-24T08:49:36Z"), "user_id" : "65675f96", "os" : "Android", "channel" : "040401" }, "count" : 1 }
{ "_id" : { "register_time" : ISODate("2016-06-24T06:29:56Z"), "user_id" : "f61d0572", "os" : "Android", "channel" : "040401" }, "count" : 1 }
{ "_id" : { "register_time" : ISODate("2016-06-24T04:13:31Z"), "user_id" : "d7d1349d", "os" : "Android", "channel" : "040401" }, "count" : 1 }
{ "_id" : { "register_time" : ISODate("2016-06-24T03:40:13Z"), "user_id" : "ecea2908", "os" : "Android", "channel" : "040401" }, "count" : 1 }
And here is the second skip
result:
{ "_id" : { "register_time" : ISODate("2016-06-24T09:05:13Z"), "user_id" : "6fde06a6", "os" : "Android", "channel" : "040401" }, "count" : 1 }
{ "_id" : { "register_time" : ISODate("2016-06-24T07:47:46Z"), "user_id" : "1e5e5712", "os" : "Android", "channel" : "040401" }, "count" : 1 }
{ "_id" : { "register_time" : ISODate("2016-06-24T05:34:55Z"), "user_id" : "47dfaa32", "os" : "Android", "channel" : "040401" }, "count" : 1 }
{ "_id" : { "register_time" : ISODate("2016-06-24T05:15:03Z"), "user_id" : "70960ae2", "os" : "Android", "channel" : "040401" }, "count" : 1 }
As you can see, the two page's register_time
are not following the same order.
How can I make different pages (skips) follow one consistent order? Thanks.
Upvotes: 4
Views: 8717
Reputation: 7951
The order matters.
Remember that $sort
must be before $skip
and $limit
. If sort is after them, weird results might be returned.
And if you want to add lookups, the $lookup
element should be at the end.
Example:
aggregate([
{ "$match" : { "type" : "xyz" } },
{ "$sort" : { "createdDateTime" : -1 } },
{ "$skip" : 50 },
{ "$limit" : 10 },
{ "$lookup" : {....
Upvotes: 1
Reputation: 9473
you need to move $sort
before $limit
and $skip
as doing $limit
you are limiting random documents from collection and next pipeline entries are based on random input
Upvotes: 11