티스토리 뷰

Offset-based paging

기본적으로 사용하게 되는 pagination 방식이다. API를 호출할 때 page, limit parameters를 사용하여 데이터를 호출한다.

// 한 페이지당 10개의 item을 보여주는 경우
const itemCount = 10;
db.items.find({  }).sort({_id:-1}).skip((page-1)* itemCount).limit(itemCount)
# API 요청 예시
curl https://api.github.com/user/repos?page=2&per_page=10

결과 list가 추가되거나 삭제되면 item이 빠지거나 2번 반복되는 경우가 생길 수 있다. 첫 번째 페이지에 10개를 요청하고 하나의 item이 지워졌다면 지워지기 전 11번째 있던 item이 10번째로 이동하게 된다. 따라서 두 번째 페이지를 요청할 때 11번째 있던 item이 누락된다.

Time-based paging

최신순으로 정렬된 결과를 반환하고 반환된 결과 중 마지막 item의 timestamp를 다음 페이지를 요청 시 사용한다.

// 한 페이지당 10개의 item을 보여주는 경우
const itemCount = 10;
let created // client에서 받은 timestamp
db.items.find({createdAt: {$lt: created }}).sort({_id:-1}).limit(itemCount)
curl https://example.com?created=1597273975343

Offset-based paging에서 발생하던 누락현상은 없어진다. 하지만 timestamp가 같은 item이 있을 경우 누락이 발생할 수 있다. 두 번째 페이지 요청 시 timestamp가 1597273975343였고 1597273975343에 생성된 item이 한개 이상이라면 두 번째 페이지 요청 시 1597273975343의 timestamp를 가지고 있는 item은 누락된다.

Cursor-based paging

Cursor-based paging은 반환된 결과의 마지막 item을 기준으로 다음 요청을 하는 것이다.

cursor를 선택할 때는 Unique, Orderable, Immutable한 field를 선택해야 한다. Time-based paging도 Cursor-based paging이지만 unique하지 않았다.

mongodb를 사용하는 경우 _id를 사용하여 Cursor-based paging을 구현할 수 있다.

const itemCount = 10;
const items = db.items.find({
  _id: { $lt: req.query.next }
}).sort({
   _id: -1
}).limit(10);

const next = items[items.length - 1]._id

생성순 정렬이 아닌 경우

_id는 Document가 새로 생성될 때 생성되어 생성 순으로 정렬되는 경우에 사용할 수 있지만 업데이트 순으로 정렬하거나 다른 기준으로 정렬되는 경우 _id를 사용할 수 없다.

_id외의 다른 field로 sorting하는 경우 아래의 코드에서와 같이 sort와 find에 모두 추가하여 query를 구성해야 한다.

const [nextUpdated, nextId] = req.query.next.split(‘_’);
const items = db.items.find({
  $or: [{
    updatedAt: { $lt: nextUpdated }
  }, {
    updatedAt: nextUpdated,
    _id: { $lt: nextId }
  }]
}).sort({
   updatedAt: -1,
   _id: -1,
}).limit(10);

const lastItem = items[items.length - 1];
const next = `${lastItem.updatedAt}_${lastItem._id}`;

updatedAt이 동일한 값이 있는 경우 _id로 구분할 수 있도록 구성한다.

Reference

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
글 보관함