Truyền trực tuyến báo cáo bằng GoogleAdsService

Để 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 chung củ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 Tìm nạp đối tượng và báo cáo Tìm nạp đối tượng và báo cáo
Phản hồi Luồng gồm các đối tượng GoogleAdsRow Các trang của đối tượng GoogleAdsRow
Các 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 được chỉ định trong truy vấn
Giới hạn hằng ngày Hạn mức hằng ngày dựa trên cấp truy cập Hạn mức hằng ngày dựa trên cấp truy cập

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 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 sẽ bắt đầu tải xuống ngay lập tức theo lô gồm đối tượng SearchGoogleAdsStreamResponse. Mã của bạn có thể lặp lại các lô đế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 trao đổ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 suất 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 bao 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 trên 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ố ảnh hưởng đến 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: SearchStream thường nhanh hơn vì tránh được nhiều chuyến khứ hồi trên mạng và 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ì SearchStream dựa vào kết nối liên tục, nên các luồng phát trực tiếp kéo 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 trên đám mây 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, 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 với 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 tỷ lệ 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 truyền 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;
}
      

curl