メインコンテンツへスキップ

Recent search のページネーション

はじめに

検索クエリは、単一の API レスポンスで返せる数より多くの Post に一致するのが一般的です。その場合、data は一連の「ページ」として返されます。ページネーションとは、データセット全体を取得するために、すべてのページを順番にリクエストする方法を指します。 以下は、recent search におけるページネーションの基本事項です。
  • recent search エンドポイントは、クエリに対して少なくとも 1 ページで応答し、追加のページが利用可能な場合は JSON レスポンス内に next_token を提供します。一致する Post を受け取るには、レスポンスにトークンが含まれなくなるまでこの処理を繰り返します。
  • next_token は失効しません。同じ next_token 値を使用した複数のリクエストは、リクエストした時期に関係なく同一の結果を受け取ります。
  • Post は UTC タイムゾーンで新しいものから古いものへ(逆時系列)で返されます。これは各ページ内だけでなく、複数ページにまたがっても同様です。
    • 最初のレスポンスの先頭の Post が、クエリに一致する最新の Post です。
    • 最後のレスポンスの末尾の Post が、クエリに一致する最も古い Post です。
  • max_results リクエストパラメータにより、レスポンスごとに返される Post の数を設定できます。デフォルトは 10 件、最大は 100 件です。
  • すべてのページネーション実装では、レスポンスのペイロードから next_token を抽出し、それを「次のページ」の検索リクエストに含めます。これらの「次のページ」リクエストの構築方法については、以下を参照してください。
recent search エンドポイントは、次の 2 つの基本的な使用パターンをサポートするよう設計されています。
  • 履歴取得 - 関心のある期間から一致する Post をリクエストします。これは通常、履歴調査を目的とした一度限りのリクエストです。検索リクエストは start_time および end_time リクエストパラメータに基づいて行うことができます。recent search エンドポイントは、最新の一致する Post から始めて、逆時系列で Post を返します。
  • ポーリング - 直近に受信した Post 以降に投稿された一致する Post をリクエストします。これらのユースケースは、ほぼリアルタイムに焦点を当てることが多く、新しい関心のある Post を「リッスン」するために高頻度でリクエストするのが特徴です。recent search エンドポイントは、この「ポーリング」パターンをサポートするために since_id リクエストパラメータを提供します。Post の ID による扱いを容易にするため、until_id リクエストパラメータも利用できます。
次に、履歴モードについて説明します。これは recent search エンドポイントのデフォルトモードであり、ページネーションの基本を示します。続いて、ポーリングのユースケースの例を説明します。ポーリングでページネーションが発生する場合、検索リクエストを管理するための追加の手順が必要になります。  

過去データの取得

このセクションでは、関心のある期間(現時点では直近7日間に限定)からの Post を、start_time と end_time リクエストパラメータを使って取得する方法を説明します。過去データのリクエストは、通常、調査や分析を目的とした一度限りのリクエストです。  期間を指定してデータを取得するのは、recent search エンドポイントの既定の動作です。検索リクエストで start_time、end_time、または since_id が指定されていない場合、end_time は「now」(実際にはクエリ時刻の30秒前)、start_time は7日前が既定値となります。 エンドポイントは、最新の Post から始まる逆時系列で、最初の「ページ」の Post を返します。レスポンスの JSON ペイロードには、追加のページがある場合に next_token も含まれます。ページ数に関係なく一致する Post をすべて収集するには、next_token が返されなくなるまでリクエストを繰り返してください。  例として、過去1週間にキーワード snow を含む Post の初回リクエストは次のとおりです: https://api.x.com/2/tweets/search/recent?query=snow レスポンスには、最新の10件の Post に加えて、JSON レスポンス内の次の「meta」属性が含まれます:
"meta": {
        "newest_id": "1204860593741553664",
        "oldest_id": "1204860580630278147",
        "next_token": "b26v89c19zqg8o3fobd8v73egzbdt3qao235oql",
        "result_count": 10
    }
次の10件のPostを取得するには、この next_token を元のリクエストに追加します。リクエストは次のとおりです: https://api.x.com/2/tweets/search/recent?query=snow&next_token=b26v89c19zqg8o3fobd8v73egzbdt3qao235oql next_token を取得して次のリクエストに含める処理は、すべての(または任意の数の)Postが収集されるまで、あるいは指定した回数のリクエストが行われるまで繰り返せます。データ完全性(クエリに一致するものをすべて収集すること)が重要なユースケースであれば、「request.next_token が null になるまで繰り返す」という単純な設計で十分です。

ポーリングとリスニングのユースケース

このセクションでは、recent search エンドポイントに since_id リクエストパラメータを指定してポーリングし、最近のPostを取得する方法を説明します。  ポーリングのユースケースでは、「関心のある新しいPostはあるか?」というクエリを継続的かつ高頻度に実行します。時間ベースの履歴ユースケースとは異なり、ポーリングのユースケースでは通常、リクエストはPostのIDに基づきます。 ポーリング利用パターンの中核は、すべての新しいPostには一意のIDがあり、Xプラットフォームから一般に昇順で「割り当て」されるという点です。あるPostのIDが別のPostより小さい場合、それは前に投稿されたことを意味します。 recent search エンドポイントは、Post IDでPostアーカイブをたどることをサポートします。エンドポイントからのレスポンスには、oldest_id と newest_id のPost IDが含まれます。ポーリングモードでは、これまでに受け取った最大/最新のIDを since_id に設定してリクエストします。  例えば、雪に関する新しいPostのクエリを5分ごとに実行し、最後に受け取ったPostのPost IDが10000だったとします。ポーリングのタイミングになったら、リクエストは次のようになります。 https://api.x.com/2/tweets/search/recent?query=snow&since_id=10000 次に、前回のリクエスト以降に7件のPostが投稿されたとします。これらはすべて1つのdata「ページ」に収まるため、next_token はありません。レスポンスには、最新(newest)のPostのPost IDが含まれます。
"meta": {
        "newest_id": "12000",
        "oldest_id": "10005",
        "result_count": 7
    }
次回のポーリングクエリを行うには、この newest_id の値を使って次の since_id パラメータを設定します: https://api.x.com/2/tweets/search/recent?query=snow&since_id=12000 追加のデータがあり、next トークンが返される場合でも、結果の最初のページに含まれる newest_id の値だけで十分です。各ページのデータには newest_id と oldest_id が含まれますが、次の定期的なポーリングリクエストに必要なのは最初のページで提供される値のみです。したがって、ポーリング設計を実装する場合や、ID 範囲での Post 検索を行う場合は、ページネーションのロジックがやや複雑になります。 ここで、さらに一致する Post が 18 件あるとします。エンドポイントは、この5分間のデータに対して、最初のレスポンスで完全なデータページと、次のページを取得するための next_token を返します。さらに、5分後の次回のポーリング間隔に必要となる最新の Post の ID も含まれます。
"meta": {
        "newest_id": "13800",
        "oldest_id": "12500",
        "next_token": "fnsih9chihsnkjbvkjbsc",
        "result_count": 10
    }
この5分間に一致するすべてのデータを取得するには、前回のリクエストと同じ since_id の値を使用し、次のリクエストで next_token を指定してください。 https://api.x.com/2/tweets/search/recent?query=snow&since_id=12000&next_token=fnsih9chihsnkjbvkjbsc
"meta": {
        "newest_id": "12300",
        "oldest_id": "12010",
        "result_count": 8
    }
この2つ目のレスポンスでは、残りの8件のPostが返され、next_token は含まれません。なお、newest_id の値(12300)は更新せず、次の since_id リクエストは最初のレスポンスの newest_id の値に基づいて行います: https://api.x.com/2/tweets/search/recent?query=snow&since_id=13800