쿼리
RecordQuery는 stream()와 함께 사용하는 스트리밍 필터입니다. 커서 이후부터 재개하거나, 시간 범위를 읽거나,
필드 값이 일치하는 항목을 필터링하거나, 제한에 도달하면 중지하는 등 추가 위주의 접근 패턴을 지원합니다. 더 풍부한 조건,
정렬 및 인덱스 기반 조회에는 쿼리 빌더를 사용하세요. 스트림에서 일반 foreach로 할 수 있는
모든 작업에는 RecordQuery가 더 효율적입니다.
RecordQuery는 변경할 수 없습니다. 각 수정 메서드는 복제된 쿼리를 반환합니다:
$query = Storh\RecordQuery::all()
->after($lastSeenId)
->time_range_ms($fromMs, $untilMs)
->where_equal('kind', 'page')
->limit(100);
foreach ($store->stream($query) as $record) {
// Records are yielded lazily.
}
after()와 time_range_ms()는 UUID 순서를 사용하므로 레코드 데이터에 타임스탬프 필드가 필요하지
않습니다. SegmentedLog에서는 작업도 건너뜁니다. ID 범위가 윈도우 바깥인 세그먼트는 열지 않으며, 세그먼트별 희소
인덱스는 처음부터 훑는 대신 첫 번째 일치 레코드 근처로 이동합니다.
where_equal()는 최상위 데이터 필드를 ===와 비교하며 스칼라 값 또는 null를 허용합니다. null 필터는 필드가 존재하면서 값이 null인 레코드와 일치합니다. 필드가 없는 레코드는 일치하지 않습니다.
커서 페이지네이션
ID는 생성 시간순으로 정렬되므로 한 페이지의 마지막 ID를 다음 페이지의 커서로 사용할 수 있습니다:
$page = iterator_to_array($store->stream(
Storh\RecordQuery::all()->after($lastSeenId)->limit(100)
), false);
$lastSeenId = [] === $page ? $lastSeenId : end($page)->id();
손상된 레코드 건너뛰기
기본적으로 스캔은 읽을 수 없는 첫 레코드에서 오류를 발생시킵니다. 해당 레코드를 건너뛰고
대신 실패를 보고하도록 하려면 continue_on_error()를 사용하세요:
$query = Storh\RecordQuery::all()->continue_on_error(
static function (string $location, Throwable $error): void {
error_log($location . ': ' . $error->getMessage());
},
);
DocStore와 segment-file:byte-offset의 위치는 레코드 ID이며,
SegmentedLog의 위치는 repair()입니다. 손상된 레코드를 실제로 정리하는 도구는 CLI입니다.