Để truy xuất các thực thể và dữ liệu báo cáo của Google Ads API, hãy sử dụng một trong các phương thức sau:
Sau đây là những điểm khác biệt chính giữa hai phương thức này:
| GoogleAdsService.SearchStream | GoogleAdsService.Search | |
|---|---|---|
| Phù hợp với mã phát hành công khai | Có | Có |
| Dịch vụ | GoogleAdsService |
GoogleAdsService |
| Trường hợp | Đang tìm nạp đối tượng và báo cáo | Đang tìm nạp đối tượng và báo cáo |
| Phản hồi | Luồng của đối tượng GoogleAdsRow |
Các trang của đối tượng GoogleAdsRow |
| Trường của phản hồi | Chỉ những người được chỉ định trong truy vấn | Chỉ những người dùng được chỉ định trong truy vấn |
| Giới hạn hằng ngày | Giới hạn hằng ngày dựa trên cấp truy cập | Giới hạn hằng ngày dựa trên cấp truy cập |
SearchStream đấu với Search
Mặc dù Search gửi nhiều yêu cầu phân trang để tải toàn bộ báo cáo xuống, nhưng SearchStream sẽ gửi một yêu cầu duy nhất và bắt đầu một kết nối gRPC liên tục với Google Ads API bất kể kích thước báo cáo.
Đối với SearchStream, các gói dữ liệu bắt đầu tải xuống ngay lập tức theo lô gồm các đối tượng SearchGoogleAdsStreamResponse. Mã của bạn có thể lặp lại các lô dữ liệu đến khi chúng đến mà không cần đợi toàn bộ luồng hoàn tất.
Bằng cách loại bỏ thời gian mạng khứ hồi cần thiết để yêu cầu từng trang riêng lẻ của phản hồi Search, SearchStream mang lại hiệu quả cao hơn so với phân trang, đặc biệt là đối với các báo cáo lớn.
Ví dụ
Ví dụ này xem xét một báo cáo gồm 100,000 hàng. Bảng sau đây trình bày chi tiết những điểm khác biệt về yêu cầu và phản hồi giữa hai phương thức này:
| SearchStream | Tìm kiếm | |
|---|---|---|
| Kích thước trang | Không áp dụng | 10.000 hàng mỗi trang |
| Số lượng yêu cầu API | 1 yêu cầu | 10 yêu cầu |
| Số lượng phản hồi của API | 1 luồng phát liên tục | 10 câu trả lời |
Các yếu tố hiệu suất
Đối với hầu hết các trường hợp sử dụng, bạn nên dùng SearchStream thay vì Search vì những lý do sau:
- Báo cáo một trang (dưới 10.000 hàng): Không có sự khác biệt đáng kể về hiệu suất giữa hai phương pháp này.
- Báo cáo nhiều trang:
SearchStreamthường nhanh hơn vì tránh được nhiều lượt khứ hồi mạng, đồng thời việc đọc hoặc ghi từ bộ nhớ đệm của ổ đĩa ít ảnh hưởng hơn. - Hiệu quả về bộ nhớ: Khi xử lý các báo cáo lớn bằng
SearchStream, hãy lặp lại các khối luồng và xử lý các hàng khi chúng đến thay vì đệm tất cả các hàng trong bộ nhớ cùng một lúc để tránh lỗi hết bộ nhớ (OOM). - Khả năng phục hồi kết nối: Vì
SearchStreamdựa vào kết nối liên tục, nên các luồng chạy trong thời gian dài có thể bị gián đoạn do mạng bị rớt hoặc hết thời gian chờ. Định cấu hình thời gian chờ RPC thích hợp và triển khai logic thử lại cho các lỗi luồng tạm thời.
Giới hạn số lượng yêu cầu
Hạn mức hoạt động hằng ngày cho cả hai phương thức đều tuân thủ hạn mức tiêu chuẩn và cấp độ truy cập của dự án Google Cloud. Một truy vấn báo cáo logic duy nhất được tính là một thao tác trong hạn mức thao tác hằng ngày của bạn, bất kể kết quả được truyền trực tuyến bằng SearchStream hay được truy xuất trên nhiều trang được lưu vào bộ nhớ đệm bằng Search có page_token. Tuy nhiên, mỗi yêu cầu Search được phân trang vẫn được tính là một lệnh gọi RPC riêng lẻ theo giới hạn số lượng yêu cầu ngắn hạn.
Ví dụ về mã
Ví dụ về mã sau đây minh hoạ cách thực thi một truy vấn báo cáo trực tuyến bằng cách sử dụng thư viện ứng dụng:
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.' )
Ruby
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; }