쿼리 커서

쿼리 커서는 애플리케이션이 쿼리 결과를 편리하게 일괄적으로 검색할 수 있게 해주므로 정수 오프셋으로 페이지를 나누는 방식보다 권장됩니다. 앱의 쿼리 구조화에 대한 자세한 내용은 쿼리를 참조하세요.

쿼리 커서

쿼리 커서를 사용하면 쿼리 오프셋의 오버헤드 발생 없이 애플리케이션에서 편리하게 일괄적으로 쿼리 결과를 검색할 수 있습니다. 검색 작업을 수행한 후 애플리케이션은 커서를 가져올 수 있습니다. 커서는 마지막으로 검색된 결과의 색인 위치를 표시하는 불투명한 base64 인코딩 문자열입니다. 애플리케이션은 이 문자열을 Datastore, Memcache, 태스크 큐 태스크 페이로드 등에 저장하거나 웹페이지에 HTTP GET 또는 POST 매개변수로 포함한 후 해당 커서를 후속 검색 작업의 시작점으로 사용하여 이전 검색이 끝난 지점부터 결과의 다음 배치를 가져올 수 있습니다. 검색 시 끝 커서를 지정하여 결과 집합이 반환되는 범위를 제한할 수도 있습니다.

오프셋과 커서 비교

Datastore가 정수 오프셋을 지원하지만 사용하지 마세요. 대신 커서를 사용하세요. 오프셋을 사용하면 건너뛴 항목이 애플리케이션에 반환되지는 않지만 내부적으로는 계속 검색됩니다. 건너뛴 항목은 쿼리의 지연 시간에 영향을 주며, 애플리케이션이 검색하는 데 소요된 읽기 작업에 대해 비용이 청구됩니다. 오프셋 대신 커서를 사용하면 이러한 모든 비용이 청구되지 않습니다.

쿼리 커서 예시

Go에서 애플리케이션은 Iterator 값의 Cursor 메서드를 호출하여 쿼리 결과를 검색한 후 커서를 가져옵니다. 애플리케이션은 커서 지점부터 추가 결과를 검색하기 위해 동일한 항목 종류, 필터, 정렬 순서를 사용하여 유사한 쿼리를 준비하고 쿼리의 Start 메서드에 커서를 전달한 후에 검색을 수행합니다.

// Create a query for all Person entities.
q := datastore.NewQuery("Person")

// If the application stored a cursor during a previous request, use it.
item, err := memcache.Get(ctx, "person_cursor")
if err == nil {
	cursor, err := datastore.DecodeCursor(string(item.Value))
	if err == nil {
		q = q.Start(cursor)
	}
}

// Iterate over the results.
t := q.Run(ctx)
for {
	var p Person
	_, err := t.Next(&p)
	if err == datastore.Done {
		break
	}
	if err != nil {
		log.Errorf(ctx, "fetching next Person: %v", err)
		break
	}
	// Do something with the Person p
}

// Get updated cursor and store it for next time.
if cursor, err := t.Cursor(); err == nil {
	memcache.Set(ctx, &memcache.Item{
		Key:   "person_cursor",
		Value: []byte(cursor.String()),
	})
}

커서 제한 사항

다음과 같은 제한사항이 커서에 적용됩니다.

  • 원본 쿼리를 수행한 동일한 애플리케이션에서만 그리고 같은 쿼리를 계속 진행할 경우에만 커서를 사용할 수 있습니다. 후속 검색 작업에서 커서를 사용하려면 동일한 항목 종류, 상위 필터, 속성 필터, 정렬 순서를 포함하여 원본 쿼리를 정확하게 다시 구성해야 합니다. 원래 생성된 쿼리와 동일하게 쿼리를 설정하지 않으면 커서를 사용하여 결과를 검색할 수 없습니다.
  • 커서는 값이 여러 개인 속성에 불일치 필터나 정렬 순서를 사용하는 쿼리에서 예상대로 작동하지 않을 수도 있습니다. 이러한 다중 값 속성에 대한 중복 제거 로직은 다음 검색까지 지속되지 않으므로 동일한 결과가 한 번 이상 반환될 수 있습니다.
  • 새로운 App Engine 출시 버전에서 내부 구현의 세부정보가 변경되면 여기에 종속된 커서가 무효화될 수 있습니다. 애플리케이션에서 이제는 유효하지 않은 커서를 사용하려고 시도하면 Datastore에서 오류를 반환합니다.

커서 및 데이터 업데이트

커서 위치는 마지막 결과가 반환된 후 결과 목록의 위치로 정의됩니다. 커서는 목록의 상대 위치가 아닙니다(오프셋이 아님). 결과에 대한 색인 스캔을 시작할 때 Datastore가 이동할 수 있는 위치를 표시하는 마커입니다. 커서를 사용하는 시점 간에 쿼리 결과가 변경되면 쿼리는 커서보다 뒤에 있는 결과에서 발생한 변경 사항만 알립니다. 쿼리의 커서 위치보다 앞에서 나타난 새 결과는 커서보다 뒤에 있는 결과를 가져오면 반환되지 않습니다. 마찬가지로, 항목이 더 이상 쿼리의 결과가 아니지만 커서보다 앞에 나타난 경우 커서보다 뒤에 나타나는 결과는 바뀌지 않습니다. 마지막으로 반환된 결과가 결과 집합에서 삭제된 경우, 커서는 다음 결과를 계속 찾을 수 있습니다.

쿼리 결과를 검색할 때 시작 커서와 끝 커서를 사용하여 Datastore에서 연속적인 결과 그룹을 반환할 수 있습니다. 시작 커서와 끝 커서를 사용하여 결과 검색 시 결과의 크기가 커서 생성 시점과 동일하다는 보장은 없습니다. 커서가 생성된 후 쿼리에서 사용되기 전에 Datastore에서 항목이 추가되거나 삭제될 수 있습니다.

다음 단계