Estou muito desapontado com as respostas aceitas nesta pergunta. Isso não será dimensionado. Se você ler as letras miúdas em cursor.skip():
O método cursor.skip() geralmente é caro porque exige que o servidor caminhe desde o início da coleção ou índice para obter a posição de deslocamento ou salto antes de começar a retornar o resultado. À medida que o deslocamento (por exemplo, pageNumber acima) aumenta, cursor.skip() se tornará mais lento e mais intensivo da CPU. Com coleções maiores, cursor.skip() pode se tornar IO vinculado.
Para obter a paginação de maneira escalável, combine um limite( ) junto com pelo menos um critério de filtro, uma data createdOn atende a muitos propósitos.
MyModel.find( { createdOn: { $lte: request.createdOnBefore } } )
.limit( 10 )
.sort( '-createdOn' )