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();