Firebase 쿼리 커서로 데이터 페이지화하기

GonnabeAlright·2022년 3월 26일
0
post-thumbnail
post-custom-banner


Cloud Firestore의 쿼리 커서를 사용하면 쿼리에 정의한 매개변수에 따라 쿼리에서 반환하는 데이터를 일정하게 분할할 수 있습니다.

쿼리 커서로 시작점과 끝점을 정의하여 다음을 수행할 수 있습니다.

  • 데이터 중 일부를 반환합니다.
  • 쿼리 결과를 페이지화합니다.

그러나 쿼리의 범위를 구체적으로 정의하려면 단순 쿼리에서 설명하는 where()를 사용해야 합니다.

쿼리에 단순 커서 추가

startAt() 또는 startAfter()메서드를 사용하여 쿼리의 시작점을 정의합니다. startAt()메서드는 시작점을 포함하고, startAfter() 메서드는 시작점을 제외합니다.

예를 들어 쿼리에 startAt(A)을 사용하면 전체 알파벳이 반환됩니다. startAfter(A)를 대신 사용하면. B-Z가 반환됩니다.

const startAtRes = await db.collection('cities')
	.orderBy('population')
	.startAt(1000000)
	.get();

마찬가지로 endAt() 또는 endBefore() 메서드를 사용하여 쿼리 결과에 대한 끝점을 정의합니다.

const endAtRes = await db.collection('cities')
	.orderBy('population')
	.endAt(1000000)
	.get();

문서 스냅샷을 사용하여 쿼리 커서 정의

문서 스냅샷을 쿼리 커서의 시작점이나 끝점으로 커서 절에 전달할 수도 있습니다. 문서 스냅샷의 값은 쿼리 커서의 값으로 사용됩니다.

예를 들어 여러 도시와 인구로 구성된 데이터 세트 중 'San Francisco'문서의 스냅샷을 만듭니다. 그런 다음 이 문서 스냅샷을 인구 쿼리 커서의 시작점으로 사용합니다. 이렇게 하면 문서 스냅샷에 정의된 San Francisco의 인구보다 인구가 더 많거나 같은 도시가 모두 반환됩니다.

const docRef = db.collection('cities').doc('SF');
const snapshot = await docRef.get();
const startAtSnapshot = db.collection('cities')
	.orderBy('population')
	.startAt(snapshot);

await startAtSnapshot.limit(10).get();

쿼리 페이지화

쿼리 커서를 limit() 메서드와 결합하여 쿼리를 페이지화합니다. 예를 들어 일괄 처리 분량의 마지막 문서를 다음 일괄 처리 분량의 커리 시작점으로 사용합니다.

const first = db.collection('cities')
	.orderBy('population')
	.limit(3);

const snapshot = await first.get();

const last = snapshot.docs[snapshot.docs.length - 1];

const next = db.collection('cities')
	.orderBy('population')
	.startAfter(last.data().population)
	.limit(3);

여러 필드를 기준으로 커서 설정

(문서 스냅샷이 아닌)필드 값을 기준으로 커서를 사용할 경우 필드를 더 추가하여 커서 위치를 더욱 정확하게 지정할 수 있습니다. 이 방법은 데이터 세트에 커서 필드의 값이 동일한 문서가 여러 개 있어 커서 위치가 불분명할 때 특히 유용합니다. 커서에 추가 필드 값을 추가하여 시작점 또는 끝점을 추가로 지정하면 모호성을 줄일 수 있습니다.

예를 들어 미국의 'Springfield'라는 도시를 모두 포함하는 데이터 세트에서 쿼리가 'Springfield'에서 시작되도록 설정하면 시작점이 여러 개 생깁니다.

커서 절에 '주'를 2차 조건으로 추가하면 Springfield의 시작점을 더 구체적으로 지정할 수 있습니다.

const startAtNameRes = await db.collection('cities')
	.orderBy('name')
	.orderBy('state')
	.startAt('Springfield')
	.get();

const startAtNameAndStateRes = await db.collection('cities')
	.orderBy('name')
	.orderBy('state')
	.startAt('Springfield', 'Missouri')
	.get();
post-custom-banner

0개의 댓글