使用 GoogleAdsService 串流報表

如要擷取 Google Ads API 實體和報表資料,請使用下列其中一種方法:

這兩種方法的主要差異如下:

GoogleAdsService.SearchStream GoogleAdsService.Search
適合用於正式版程式碼 是 是
服務 GoogleAdsService GoogleAdsService
情境 擷取物件和報表 擷取物件和報表
回應 串流 GoogleAdsRow 個物件 GoogleAdsRow 物件的頁面
回應的欄位 只傳回查詢中指定的屬性 只傳回查詢中指定的屬性
每日上限 根據存取層級設定每日上限 根據存取層級設定每日上限

Search 會傳送多個分頁請求來下載完整報表,而 SearchStream 則會傳送單一請求,並與 Google Ads API 建立持續性 gRPC 連線,不受報表大小影響。

如果是 SearchStream,系統會立即開始下載資料封包,並以 SearchGoogleAdsStreamResponse 物件為批次單位。程式碼可以逐一疊代處理傳入的批次,不必等待整個串流完成。

Search可消除要求 SearchStream 回應中每個網頁所需的來回網路時間,因此效能比分頁功能更出色,尤其是在處理大型報表時。

範例

這個範例會查看包含 100,000 列的報表。下表列出這兩種方法的要求和回應差異:

SearchStream 搜尋
頁面大小 不適用 每頁 10,000 列
API 要求數 1 項要求 10 項要求
API 回應數量 1 個連續串流 10 則回覆

效能因素

在大多數情況下,我們建議使用 SearchStream,而非 Search,原因如下:

  • 單頁報表 (少於 10,000 列):這兩種方法在效能方面沒有顯著差異。
  • 多頁面報表: SearchStream通常速度較快,因為可避免多次網路往返,且從磁碟快取讀取或寫入資料的影響較小。
  • 記憶體效率:使用 SearchStream 處理大型報表時,請逐一疊代串流區塊,並在資料列抵達時處理,而不是一次緩衝處理所有資料列,以免發生記憶體不足 (OOM) 錯誤。
  • 連線穩定性:由於 SearchStream 依賴持續連線,因此網路中斷或截止時間逾時可能會導致長時間執行的串流中斷。設定適當的 RPC 超時,並針對暫時性串流錯誤實作重試邏輯。

頻率限制

兩種方法的每日作業限制都符合 Google Cloud 專案的標準限制和存取層級。無論結果是否使用 SearchStream 串流,或使用 Search 和 page_token 從多個快取頁面擷取,單一邏輯報表查詢都會計為每日作業配額的一項作業。不過,每項分頁 Search 要求仍會計為短期速率限制中的個別 RPC 呼叫。

程式碼範例

下列程式碼範例說明如何使用用戶端程式庫,執行串流報表查詢:

Java

private void runExample(GoogleAdsClient googleAdsClient, long customerId) {
  try (GoogleAdsServiceClient googleAdsServiceClient =
      googleAdsClient.getLatestVersion().createGoogleAdsServiceClient()) {
    String query = "SELECT campaign.id, campaign.name FROM campaign ORDER BY campaign.id";
    // Constructs the SearchGoogleAdsStreamRequest.
    SearchGoogleAdsStreamRequest request =
        SearchGoogleAdsStreamRequest.newBuilder()
            .setCustomerId(Long.toString(customerId))
            .setQuery(query)
            .build();

    // Creates and issues a search Google Ads stream request that will retrieve all campaigns.
    ServerStream<SearchGoogleAdsStreamResponse> stream =
        googleAdsServiceClient.searchStreamCallable().call(request);

    // Iterates through and prints all of the results in the stream response.
    for (SearchGoogleAdsStreamResponse response : stream) {
      for (GoogleAdsRow googleAdsRow : response.getResultsList()) {
        System.out.printf(
            "Campaign with ID %d and name '%s' was found.%n",
            googleAdsRow.getCampaign().getId(), googleAdsRow.getCampaign().getName());
      }
    }
  }
}
      

C#

public void Run(GoogleAdsClient client, long customerId)
{
    // Get the GoogleAdsService.
    GoogleAdsServiceClient googleAdsService = client.GetService(
        Services.V25.GoogleAdsService);

    // Create a query that will retrieve all campaigns.
    string query = @"SELECT
                    campaign.id,
                    campaign.name,
                    campaign.network_settings.target_content_network
                FROM campaign
                ORDER BY campaign.id";

    try
    {
        // Issue a search request.
        googleAdsService.SearchStream(customerId.ToString(), query,
            delegate (SearchGoogleAdsStreamResponse resp)
            {
                foreach (GoogleAdsRow googleAdsRow in resp.Results)
                {
                    Console.WriteLine("Campaign with ID {0} and name '{1}' was found.",
                        googleAdsRow.Campaign.Id, googleAdsRow.Campaign.Name);
                }
            }
        );
    }
    catch (GoogleAdsException e)
    {
        Console.WriteLine("Failure:");
        Console.WriteLine($"Message: {e.Message}");
        Console.WriteLine($"Failure: {e.Failure}");
        Console.WriteLine($"Request ID: {e.RequestId}");
        throw;
    }
}
      

PHP

public static function runExample(GoogleAdsClient $googleAdsClient, int $customerId)
{
    $googleAdsServiceClient = $googleAdsClient->getGoogleAdsServiceClient();
    // Creates a query that retrieves all campaigns.
    $query = 'SELECT campaign.id, campaign.name FROM campaign ORDER BY campaign.id';
    // Issues a search stream request.
    /** @var GoogleAdsServerStreamDecorator $stream */
    $stream = $googleAdsServiceClient->searchStream(
        SearchGoogleAdsStreamRequest::build($customerId, $query)
    );

    // Iterates over all rows in all messages and prints the requested field values for
    // the campaign in each row.
    foreach ($stream->iterateAllElements() as $googleAdsRow) {
        /** @var GoogleAdsRow $googleAdsRow */
        printf(
            "Campaign with ID %d and name '%s' was found.%s",
            $googleAdsRow->getCampaign()->getId(),
            $googleAdsRow->getCampaign()->getName(),
            PHP_EOL
        );
    }
}
      

Python

def main(client: GoogleAdsClient, customer_id: str) -> None:
    ga_service: GoogleAdsServiceClient = client.get_service("GoogleAdsService")

    query: str = """
        SELECT
          campaign.id,
          campaign.name
        FROM campaign
        ORDER BY campaign.id"""

    # Issues a search request using streaming.
    stream: Iterator[SearchGoogleAdsStreamResponse] = ga_service.search_stream(
        customer_id=customer_id, query=query
    )

    for batch in stream:
        rows: List[GoogleAdsRow] = batch.results
        for row in rows:
            print(
                f"Campaign with ID {row.campaign.id} and name "
                f'"{row.campaign.name}" was found.'
            )
      

小茹

def get_campaigns(customer_id)
  # GoogleAdsClient will read a config file from
  # ENV['HOME']/google_ads_config.rb when called without parameters
  client = Google::Ads::GoogleAds::GoogleAdsClient.new

  responses = client.service.google_ads.search_stream(
    customer_id: customer_id,
    query: 'SELECT campaign.id, campaign.name FROM campaign ORDER BY campaign.id',
  )

  responses.each do |response|
    response.results.each do |row|
      puts "Campaign with ID #{row.campaign.id} and name '#{row.campaign.name}' was found."
    end
  end
end
      

Perl

sub get_campaigns {
  my ($api_client, $customer_id) = @_;

  # Create a search Google Ads stream request that will retrieve all campaigns.
  my $search_stream_request =
    Google::Ads::GoogleAds::V25::Services::GoogleAdsService::SearchGoogleAdsStreamRequest
    ->new({
      customerId => $customer_id,
      query      =>
        "SELECT campaign.id, campaign.name FROM campaign ORDER BY campaign.id"
    });

  # Get the GoogleAdsService.
  my $google_ads_service = $api_client->GoogleAdsService();

  my $search_stream_handler =
    Google::Ads::GoogleAds::Utils::SearchStreamHandler->new({
      service => $google_ads_service,
      request => $search_stream_request
    });

  # Issue a search request and process the stream response to print the requested
  # field values for the campaign in each row.
  $search_stream_handler->process_contents(
    sub {
      my $google_ads_row = shift;
      printf "Campaign with ID %d and name '%s' was found.\n",
        $google_ads_row->{campaign}{id}, $google_ads_row->{campaign}{name};
    });

  return 1;
}
      

curl