1

I want to sort all docs by field x (multiple docs can have same value on this field). Then every time I press "next", it loads the 10 more docs.

If multiple docs have the same value, they can be displayed at whatever order among them, it doesn't matter.

Since skip() is inefficient on large dataset, how do this efficiently? No pagination number needed, only infinite scroll.

Community
  • 1
  • 1
Saitama
  • 477
  • 6
  • 18

1 Answers1

0

If you don't require pagination number, then you can just utilise a monotonically increasing unique id values; such as _id with ObjectId().

Using your example:

/* Value of first scroll record, and to be updated every iteration */
var current_id;

var scroll_size = 10; 

db.collection.find({_id: {$lt: current_id}}).
                    limit(scroll_size).
                    sort({
                           _id: -1, 
                             x: 1   // Depending on your use case
                    });

The example above will give you most recent records. Depending on your use case you would have to decide what to do with newly inserted document.

If you are using a different field than _id to scroll through, make sure you add appropriate indexes on the field.

Wan B.
  • 18,367
  • 4
  • 54
  • 71
  • But this doesn't give records that are are sorted by x, right? This is sorted by _id – Saitama Jul 23 '16 at 06:59
  • As you can see in the example of `sort()`, the result is sorted by both `_id` AND `x`. You can also try to either A) include `x` in the matching part alongside `_id` or B) only use 'x' in the matching part. What is the value of 'x' ? – Wan B. Jul 25 '16 at 00:27
  • @WanBachtiar Yes, it's sorted by `x` but if sorting by `x` changes the order, this won't work correctly anymore as your `{_id: {$lt: current_id}` makes no sense anymore. – FINDarkside Apr 30 '19 at 10:23