برای بازیابی دادههای گزارشدهی و نهادهای Google Ads API، از یکی از این روشها استفاده کنید:
در اینجا تفاوتهای اصلی بین این دو روش آورده شده است:
| GoogleAdsService.SearchStream | GoogleAdsService.Search | |
|---|---|---|
| مناسب برای کد تولید | بله | بله |
| سرویس | GoogleAdsService |
GoogleAdsService |
| سناریو | درحال واکشی اشیاء و گزارشها | درحال واکشی اشیاء و گزارشها |
| پاسخ | جاریسازی اشیای GoogleAdsRow |
صفحههای GoogleAdsRow شیء |
| فیلدهای پاسخ | فقط موارد مشخصشده در پُرسمان | فقط موارد مشخصشده در پُرسمان |
| محدویتهای روزانه | حدود روزانه براساس سطوح دسترسی | حدود روزانه براساس سطوح دسترسی |
SearchStream مقابل Search
درحالیکه Search چندین درخواست صفحهبندیشده برای بارگیری کل گزارش ارسال میکند، SearchStream یک درخواست واحد ارسال میکند و بدون توجه به اندازه گزارش، اتصال gRPC پایداری با Google Ads API برقرار میکند.
برای SearchStream، بستههای داده بلافاصله بهصورت دستههای
SearchGoogleAdsStreamResponse شیء شروع به بارگیری میکنند. کد شما میتواند
دستههای ورودی را بهمحض رسیدن تکرار کند، بدون اینکه منتظر بماند تا کل
جاریسازی تمام شود.
با حذف زمان شبکه رفتوبرگشت موردنیاز برای درخواست هر صفحه از پاسخ Search، SearchStream عملکرد بهتری نسبتبه صفحهبندی ارائه میدهد، بهویژه برای گزارشهای بزرگ.
مثال
این مثال گزارشی را نشان میدهد که شامل 100,000 ردیف است. جدول زیر تفاوتهای درخواست و پاسخ بین این دو روش را نشان میدهد:
| SearchStream | جستجو | |
|---|---|---|
| اندازه صفحه | نامربوط | ۱۰٬۰۰۰ ردیف در هر صفحه |
| تعداد درخواستهای میانای برنامهسازی کاربردی | ۱ درخواست | ۱۰ درخواست |
| تعداد پاسخهای میانای برنامهسازی کاربردی | ۱ جاریسازی پیوسته | ۱۰ پاسخ |
عوامل عملکرد
برای اکثر موارد استفاده، SearchStream را بهدلایل زیر بر Search ترجیح میدهیم:
- گزارشهای تکصفحهای (زیر ۱۰٬۰۰۰ ردیف): تفاوت عملکرد قابلتوجهی بین این دو روش وجود ندارد.
- گزارشهای چندصفحهای:
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
پرل
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; }