如要擷取 Google Ads API 實體和報表資料,請使用下列其中一種方法:
這兩種方法的主要差異如下:
| GoogleAdsService.SearchStream | GoogleAdsService.Search | |
|---|---|---|
| 適合用於正式版程式碼 | 是 | 是 |
| 服務 | GoogleAdsService |
GoogleAdsService |
| 情境 | 擷取物件和報表 | 擷取物件和報表 |
| 回應 | 串流 GoogleAdsRow 個物件 |
GoogleAdsRow 物件的頁面 |
| 回應的欄位 | 只傳回查詢中指定的屬性 | 只傳回查詢中指定的屬性 |
| 每日上限 | 根據存取層級設定每日上限 | 根據存取層級設定每日上限 |
SearchStream對Search
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; }