عرض التقارير باستخدام GoogleAdsService

لاسترداد عناصر Google Ads API وبيانات التقارير، استخدِم إحدى الطريقتَين التاليتَين:

في ما يلي الفروق الرئيسية بين الطريقتَين:

GoogleAdsService.SearchStream GoogleAdsService.Search
مناسب لرمز الإنتاج نعم نعم
الخدمة GoogleAdsService GoogleAdsService
السيناريو جارٍ جلب العناصر والتقارير استرداد الكائنات والتقارير
الردّ مجموعة من عناصر GoogleAdsRow صفحات من عناصر GoogleAdsRow
حقول الردّ تلك المحدّدة في طلب البحث فقط الحسابات المحدّدة في طلب البحث فقط
الحدود اليومية الحدود اليومية استنادًا إلى مستويات الوصول الحدود اليومية استنادًا إلى مستويات الوصول

بينما تُرسِل Search طلبات متعددة مقسّمة على صفحات لتنزيل تقرير كامل، تُرسِل SearchStream طلبًا واحدًا وتبدأ اتصال gRPC دائمًا مع Google Ads API بغض النظر عن حجم التقرير.

بالنسبة إلى SearchStream، يبدأ تنزيل حِزم البيانات على الفور على دفعات من عناصر SearchGoogleAdsStreamResponse. يمكن أن يتكرر الرمز البرمجي على دفعات واردة أثناء وصولها بدون انتظار انتهاء البث بأكمله.

من خلال إلغاء مدة إرسال البيانات واستقبالها على الشبكة المطلوبة لطلب كل صفحة فردية من استجابة Search، يوفّر SearchStream أداءً أفضل من تقسيم المحتوى إلى صفحات، خاصةً بالنسبة إلى التقارير الكبيرة.

مثال

يتناول هذا المثال تقريرًا يتألف من 100,000 صف. يوضّح الجدول التالي الاختلافات بين الطلبات والردود في الطريقتَين:

SearchStream بحث
حجم الصفحة غير سارٍ ‫10,000 صف في كل صفحة
عدد طلبات البيانات من واجهة برمجة التطبيقات طلب واحد ‫10 طلبات
عدد الردود من واجهة برمجة التطبيقات بث مباشر واحد متواصل ‫10 ردود

عوامل الأداء

في معظم حالات الاستخدام، ننصحك باستخدام SearchStream بدلاً من Search للأسباب التالية:

  • التقارير المكوّنة من صفحة واحدة (أقل من 10,000 صف): لا توجد اختلافات كبيرة في الأداء بين الطريقتَين.
  • التقارير المتعدّدة الصفحات: يكون SearchStream أسرع عادةً لأنّه يتجنّب رحلات الذهاب والعودة المتعدّدة عبر الشبكة، كما أنّ القراءة من ذاكرة التخزين المؤقت للقرص أو الكتابة فيها تكون أقل تأثيرًا.
  • كفاءة الذاكرة: عند معالجة تقارير كبيرة باستخدام SearchStream، يجب تكرار العملية على أجزاء من البيانات ومعالجة الصفوف فور وصولها بدلاً من تخزين جميع الصفوف مؤقتًا في الذاكرة في الوقت نفسه لتجنُّب أخطاء نفاد الذاكرة (OOM).
  • مرونة الاتصال: نظرًا لأنّ SearchStream يعتمد على اتصال مستمر، يمكن أن تنقطع عمليات البث الطويلة بسبب انقطاع الشبكة أو انتهاء المهلة المحددة. اضبط مهلات RPC المناسبة ونفِّذ منطق إعادة المحاولة لأخطاء البث المؤقتة.

حدود معدّل الاستخدام

تلتزم حدود العمليات اليومية لكلا الطريقتين بالحدود العادية ومستويات الوصول لمشروعك على Google Cloud. يتم احتساب طلب البحث المنطقي الواحد للتقرير كعملية واحدة ضمن حصة العمليات اليومية بغض النظر عما إذا كانت النتيجة يتم بثها باستخدام SearchStream أو استردادها عبر صفحات مخزنة مؤقتًا متعددة باستخدام Search مع page_token. ومع ذلك، لا يزال كل طلب Search مقسّم إلى صفحات يُحتسب كطلب RPC فردي ضمن حدود المعدّل على المدى القصير.

مثال على الرمز البرمجي

يوضّح مثال الرمز البرمجي التالي كيفية تنفيذ طلب بحث عن تقرير البث المباشر باستخدام مكتبات البرامج:

جافا

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