カーソルベースのページネーションとは何か?トークンとトレードオフ
Scrapeless Agent Browser は、自動化処理が動的な結果インターフェースをナビゲートする一方で、アプリケーションがページネーション状態と収集したレコードを追跡できるようにします。
要約
- カーソルは継続位置を識別する。 API がその構造を明示的に文書化していない限り、トークンは不透明なものとして扱う。
- 安定した順序付けには決定論的なタイブレーカーが必要である。 タイムスタンプだけでは同じ瞬間に作成されたレコードを区別できない場合がある。
- カーソルページネーションはスナップショットを意味しない。 同時挿入・削除・更新は依然としてサービスの一貫性契約に依存する。
- チェックポイントにはカーソルだけでなくクエリも含まれる。 コミット済みの継続状態を進める前にレコードを保存する。
カーソルは特定の順序付きクエリを継続する
カーソルベースのページネーションは結果集合をページに分割し、クライアントに継続位置を与える。サーバーにレコードを何件スキップするかを要求する代わりに、クライアントは前のレスポンスから得た継続値を返す。サーバーはその値をクエリの並び替えとフィルタリング規則の中で解釈する。このためカーソルは、特定のコレクション走査に関連付けられて初めて意味を持つ。
cursor という語は、1 つの普遍的なパラメータ名やデータ構造を規定するものではない。REST API は next-page token や next link を公開することもあれば、GraphQL の connection は edge cursor とページ情報を公開することもある。ループを構築する前に、選択した API のコントラクトを読むこと。cursor という名前のパラメータを当てずっぽうで送るクライアントは、有効な HTTP リクエストを送っていても、サービス側では意図したページネーション操作とは別の意味で解釈してしまう可能性がある。
AIP-158 page-token guidance は、ページトークンを不透明なものとして扱い、継続性を他のリクエスト引数に結び付けている。その設計により、クライアントはバックエンドの内部表現から独立していられる。トークンは位置をエンコードしているかもしれないし、サーバー側状態を参照しているかもしれないし、保護されたクエリの詳細を運んでいるかもしれない。その見た目だけではサービスがどの仕組みを使っているかは証明できず、クライアントが正しく継続するためにその知識を必要とすべきではない。なぜ決定論的な順序付けが重要なのか
決定論的な順序付けにより、すべてのレコードに継続境界に対する明確な位置が与えられる。一意でないタイムスタンプで並び替えると、ページの端に複数のレコードが同点で残ってしまうことがある。典型的な keyset 設計では、ソート順に変更不可能な一意識別子を追加し、境界が完全な順序キーを指すようにする。具体的な選択はデータベースとアプリケーションのデータモデルに依存する。
作成時刻とレコード ID で並び替えられた仮想的なフィードを考えてみよう。次のページは現在のページの最後のペアの直後から始まり、同じ並び替え方向を使う。複数のレコードが同じ作成時刻を共有している場合、どれがすでに訪問済みかは ID によって決まる。これは Scrapeless のエンドポイントの説明でも、特定のデータベース実行計画に関する約束でもなく、概念的な例である。
The PostgreSQL ordering guidance は、制限されたクエリ結果になぜ予測可能な順序が必要なのか、またスキップされたオフセット行でもなぜサーバー側の処理が必要なのかを説明している。適切なインデックスは効率的な keyset ルックアップを支援できるが、カーソルページネーションだけではそのインデックスの存在は証明できない。自分が運用するバックエンドを評価するときは、API のパラメータ名から速度を推測するのではなく、実際のクエリプランを確認すること。
カーソル、オフセット、キーセットは関連する用語である
オフセットページネーションは、何行スキップするかで位置を識別する一方、カーソルはサービスのトークン契約を通じて継続境界を識別する。キーセットページネーションは、その境界を順序付きのフィールド値で実装するための一般的なデータベース手法である。API は内部で別の方法を使っていても、不透明なカーソルを公開している場合がある。性能に関する評価を行う際には、公開インターフェースとストレージアルゴリズムを切り離して考えること。
オフセットページネーションは、なじみのあるページ番号ナビゲーションや、選択したオフセットへの直接ジャンプをサポートできる。カーソル走査はしばしば順次継続を優先し、任意のページジャンプをサポートしないことがある。どちらのインターフェースも、正確な総件数を自動的に安価に提供するわけではない。20 ページ目へのジャンプ、保存された位置の保持、後ろ向きの閲覧といったプロダクト要件は、想定に頼らず、文書化された API の挙動に照らして評価する必要がある。
| 機能 | オフセット | カーソル |
|---|---|---|
| 位置 | スキップ量またはページ番号 | サーバーが提供する位置またはリンク |
| 直接ジャンプ | 一定の範囲内でサポートされることが多い | サービスがサポートしている場合にのみ可能 |
| データ変更 | 位置が変動する可能性がある | 順序と一貫性に依存する |
| クライアント状態 | クエリとページ位置 | クエリと不透明なカーソル |
GraphQL 接続は特定のコントラクトを定義している
The GraphQL Cursor Connections Specification は、connection と edge の構造、前方および後方ページネーションの引数、そしてページ情報を定義している。そのモデルでは、カーソルは edge に属し、ページ情報はさらに edge が利用可能かどうかを記述する。これらのフィールド名はその仕様における慣習であり、カーソルを使うすべての API に必須の名称ではない。
前方走査では一般的に、after カーソルとともにページサイズを使用し、後方走査では対応する before 境界を使用する。connection 仕様では、edge の順序がこれらの方向で一貫していることが求められる。ユーザーが後ろ向きに移動する際、コレクションのビジネス上の順序が理由もなく反転してはならない。実装とクライアントは、表示順と走査方向のどちらについて議論しているのかを合意する必要がある。
ページ長だけから推定するのではなく、ドキュメント化された終了条件を使用してください。一部の API は、継続を提供しながら要求数より少ない件数を返すことがあります。別の API では、欠けているトークンや false の継続フラグによって最終ページを定義します。見えるレコードが 1 件もないレスポンスも、慎重な解釈が必要です。権限、フィルタリング、エンドポイント固有のページネーション動作が、そのページが何を表しているかに影響する可能性があります。
カーソルは変化し続けるデータセットを固定しない
カーソルベースのページネーションは、すべてのページに同じデータベーススナップショットを自動的に与えるわけではありません。サービスは各ページを現在のデータに対して評価できます。新しいレコードが継続境界より前に現れたり、既存レコードが削除されたり、変更されうるソートフィールドによってレコードが境界をまたいで移動したりします。そうした変化が欠落や重複観測を引き起こすかどうかは、実装とその一貫性ポリシーに依存します。
履歴エクスポートの場合は、ドキュメント化されたスナップショット、エクスポートジョブ、または安定した上限境界を探してください。ライブフィードの場合は、目的が固定された母集団を列挙することなのか、現在のエントリを観測することなのかを定義してください。これらは異なる作業です。ハイウォーターマークは取得範囲を記述するのに役立ちますが、ソースが必要な順序付けとフィルタリングの保証をサポートしている場合にのみ使用すべきです。
宛先側にレコードの識別子を保持し、繰り返し観測を認識できるようにしてください。重複排除によって重複行は防げますが、見えていないレコードが決して飛ばされなかったことを証明することはできません。ソースの明示的な完了シグナルと取得クエリの境界を用いてカバレッジを報告してください。インターフェースを完全に走査したということと、履歴在庫を完全に網羅したということは、常に同じ意味とは限りません。
フィルターを保持し、チェックポイントを慎重にコミットする
継続トークンは、それを生成したクエリと一緒に移動させるべきです。コレクション、フィルタ、ソート順、その他の関連引数を網羅するクエリのフィンガープリントを保存してください。ユーザーがフィルタを変更した場合、サービスが古いトークンと新しいクエリの組み合わせを明示的にサポートしていない限り、新しいトラバーサルを開始してください。無効なトークンは、コレクションが空である証拠としてではなく、調査すべき契約上の問題として扱ってください。
次の継続状態をコミットする前に、そのページのレコードをコミットしてください。チェックポイントは、実際に永続ストレージに到達したものを記述すべきです。受け入れたレコード件数、利用可能な場合は最後に完了したページの識別子、ソースがさらなるデータを報告したかどうかを含めてください。共有ログには機密性の高いトークン値を残さないようにしてください。不透明なトークンは、クライアント側で中身を検査しないよう指示されていても、情報を含んでいる可能性があります。
トークンの有効期間も重要です。サーバー状態型のトークンは期限切れになることがあり、自己完結型トークンは認可コンテキストや署名ポリシーに結び付けられている場合があります。長時間実行のエクスポートを計画する前に、ドキュメント化された保持期間を確認してください。 SCIM cursor pagination standard は、継続属性を含む、特定の標準化されたカーソル契約の一例を示しています。その規則を無関係な API に投影すべきではありません。
ブラウザーインターフェースは基盤となるカーソルを隠すことがある
「さらに読み込む」ボタンや無限スクロールリストは、ページ URL にカーソルを露出させずに内部的にカーソルを使用している場合があります。ユーザーが目にする操作はブラウザーのページネーションインターフェースであり、ネットワークリクエストがデータの継続を担っています。ページとあなたの認可が許す挙動から始めてください。内部トークンをでっち上げたり、ドキュメント化されていないエンドポイントが安定した公開契約であると想定したりしないでください。
Scrapeless Agent Browser は、認可済みの結果ナビゲーションタスクのためのブラウザー環境を提供できます。その環境を理解するには Agent Browser の概念 を、可視的なナビゲーションの種類を見分けるには ブラウザーページネーションパターン を参照してください。コレクターは依然としてレコードの識別子、有限のトラバーサル範囲、明確な停止条件を必要とします。レビュー Scrapeless の料金 でセッションコストを見積もる際には確認しつつも、データセットの品質はセッション時間とは独立して評価してください。仮想的なカタログ取得では、ページが新しいカードを追加した後に表示される各商品 ID を記録し、インターフェースが終了を示した時点で停止するかもしれません。そのプロセスは、基盤となるカタログのトランザクションスナップショットを主張することなく、観測されたブラウザートラバーサルを検証できます。
要件に合った場合にカーソルページネーションを選択する
カーソルページネーションは、順序付けられたコレクションへの逐次アクセスがプロダクト要件に適合するときに有用です。適切なバックエンド設計であれば、大きなオフセットのコストを回避でき、ページ番号よりも明確に安定した継続境界を表現できます。一方で、ユーザーが任意のページジャンプを必要とする場合や、トークンの有効期間より長く存続しなければならない耐久的なエクスポートには不向きです。
クエリの順序、継続契約、終了マーカー、トークンの有効期間、一貫性の挙動をまとめて評価してください。収集を拡大する前に、それらの判断をコンシューマー側の受け入れ条件に書き込んでおきましょう。最終的なデータセットの品質は、それらすべてに依存します。正しく扱われた不透明トークンは信頼できるトラバーサルの一要素にすぎず、認可、ストレージ、カバレッジは周辺アプリケーションの責任として残ります。
結論
カーソルは 1 つの順序付けられたクエリの継続状態として扱い、サービス側の終了条件を保持し、前進する前にストレージへのコミットを行ってください。カーソルページネーションは効率的な逐次アクセスを支援できますが、防御可能なデータセットには明確な一貫性境界も必要です。長いトラバーサルを完了と見なす前に、その境界を確立してください。
Web データワークフローを構築する
コレクターがページネーション状態を記録し、データセットカバレッジを検証する一方で、動的ナビゲーションには Agent Browser を使用してください。
今すぐ登録して $5 の無料クレジットを獲得 — クレジットカード不要.
$5 クレジットを受け取る →FAQ
カーソルベースのページネーションはキーセットページネーションと同じですか?
カーソルベースのページネーションは、必ずしもキーセットページネーションと同一ではありません。カーソルは API の継続インターフェースであり、キーセットページネーションはそれを実装するためによく使われるデータベース手法です。トークンの背後には別のバックエンドメカニズムが隠れている場合があるため、インターフェースだけでなく、実装上の証拠から効率性を評価してください。
クライアントは不透明カーソルをデコードしてもよいですか?
クライアントは、不透明カーソルを解釈されない値として扱うべきです。内容が読めるように見えたとしても、デコードして代替トークンを構築することは、未公開の内部仕様への依存を生みます。トークンは API 仕様どおりにそのまま返し、関連するクエリ設定を保持してください。
カーソルページネーションは、重複や欠落レコードを完全に防ぎますか?
カーソルページネーションは、すべての重複レコードや欠落レコードを防ぐわけではありません。データの可変性やリクエストごとの一貫性モデルは、依然として走査に影響し得ます。決定的なソート順を使用し、可能であればスナップショット境界を文書化し、記録の ID を保存しつつ、取得時点での一貫性の制約を報告してください。
カーソルページネーションで任意のページに直接ジャンプできますか?
カーソルページネーションが任意ページへのジャンプをサポートするかどうかは、その機能をサービスが提供している場合に限られます。多くのカーソルインターフェースは、順次トラバース用に設計されています。任意ページの直接選択が必要なプロダクトは、そのインターフェースを選択したりその挙動を約束したりする前に、API がどのようなナビゲーションをサポートしているかを確認すべきです。
ページネーションのチェックポイントには何を含めるべきですか?
ページネーションのチェックポイントには、コミット済みの継続状態と、それを生成したクエリ定義を含めるべきです。さらに、ストレージへの進捗と、ソース側の完了シグナルも記録してください。受け入れ済みレコードが保存された後にのみチェックポイントを前進させ、機密性の高いクエリコンテキストが露出し得る場合にはカーソル値を保護してください。