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