রিপোর্ট করার প্রাথমিক তথ্য

ভূমিকা

API-এর মাধ্যমে কীভাবে রিপোর্ট রান ও ডাউনলোড করতে হয় তা এই নির্দেশিকা থেকে জানতে পারবেন। এতে আগে থেকে সেভ করা রিপোর্ট কোয়েরি ব্যবহার করা এবং অ্যাড হক রিপোর্ট কোয়েরি তৈরি করা, উভয়ই কভার করা হয়।

পূর্বশর্ত

Primer

Ad Manager-এ রিপোর্টিং সম্পর্কে আপনার কোনও ধারণা না থাকলে, Ad Manager UI-তে কীভাবে রিপোর্ট রান করতে হয় তার ওভারভিউ পেতে নতুন রিপোর্ট তৈরি করুন বিকল্প দেখুন। UI-তে আউটপুটের প্রিভিউ এবং কোন কলাম ও ডাইমেনশনের কম্বিনেশন কাজ করবে তা ব্যাখ্যা করার জন্য টুলটিপ আছে। জটিল রিপোর্ট কোয়েরি তৈরি করার সময়, প্রথমে UI-তে এটি তৈরি করা এবং তারপর API-এর মাধ্যমে কোয়েরি ফিরিয়ে আনা সহজ হতে পারে।

সেভ করা ReportQuery ফিরিয়ে আনা হচ্ছে

ReportQuery অবজেক্টে রিপোর্টের সব বিবরণ থাকে। আপনি Ad Manager UI-তে রিপোর্ট কোয়েরি তৈরি করতে পারেন এবং ReportService.getSavedQueriesByStatement পদ্ধতির মাধ্যমে সেগুলি ফিরিয়ে আনতে পারেন। UI-তে কোনও কোয়েরি দেখার সময় সেভ করা কোয়েরি আইডি URL-এ অন্তর্ভুক্ত করা হয়। যেমন, এই URL-এ https://www.google.com/admanager/1234#reports/report/detail/report_id=456789 কোয়েরি আইডি হল 456789।

কোনও কোয়েরি আপনার API ভার্সনের সাথে মানানসই না হলে, SavedQuery.reportQuery null হবে এবং SavedQuery.isCompatibleWithApiVersion false হবে।

মানানসই সেভ করা কোয়েরি পরিবর্তন করে বা না করে চালানো যেতে পারে।

Java

    StatementBuilder statementBuilder =
        new StatementBuilder()
            .where("id = :id")
            .orderBy("id ASC")
            .limit(1)
            .withBindVariableValue("id", savedQueryId);

    SavedQueryPage page = reportService.getSavedQueriesByStatement(statementBuilder.toStatement());
    SavedQuery savedQuery = Iterables.getOnlyElement(Arrays.asList(page.getResults()));

    if (!savedQuery.getIsCompatibleWithApiVersion()) {
      throw new IllegalStateException("The saved query is not compatible with this API version.");
    }

    ReportQuery reportQuery = savedQuery.getReportQuery();
    

Python

  statement = (ad_manager.StatementBuilder(version='v202608')
               .Where('id = :id')
               .WithBindVariable('id', int(saved_query_id))
               .Limit(1))

  response = report_service.getSavedQueriesByStatement(
      statement.ToStatement())

  if 'results' in response and len(response['results']):
    saved_query = response['results'][0]

    if saved_query['isCompatibleWithApiVersion']:
      report_job = {}

      # Set report query and optionally modify it.
      report_job['reportQuery'] = saved_query['reportQuery']
    

PHP

      $statementBuilder = (new StatementBuilder())->where('id = :id')
          ->orderBy('id ASC')
          ->limit(1)
          ->withBindVariableValue('id', $savedQueryId);

      $savedQueryPage = $reportService->getSavedQueriesByStatement(
          $statementBuilder->toStatement()
      );
      $savedQuery = $savedQueryPage->getResults()[0];

      if ($savedQuery->getIsCompatibleWithApiVersion() === false) {
          throw new UnexpectedValueException(
              'The saved query is not compatible with this API version.'
          );
      }

      $reportQuery = $savedQuery->getReportQuery();
    

C#

StatementBuilder statementBuilder = new StatementBuilder()
    .Where("id = :id")
    .OrderBy("id ASC")
    .Limit(1)
    .AddValue("id", savedQueryId);

SavedQueryPage page =
    reportService.getSavedQueriesByStatement(statementBuilder.ToStatement());
SavedQuery savedQuery = page.results[0];

if (!savedQuery.isCompatibleWithApiVersion)
{
    throw new InvalidOperationException("Saved query is not compatible with this " +
        "API version");
}

// Optionally modify the query.
ReportQuery reportQuery = savedQuery.reportQuery;
    

Ruby

  statement = ad_manager.new_statement_builder do |sb|
    sb.where = 'id = :saved_query_id'
    sb.with_bind_variable('saved_query_id', saved_query_id)
  end

  saved_query_page = report_service.get_saved_queries_by_statement(
      statement.to_statement()
  )

  unless saved_query_page[:results].nil?
    saved_query = saved_query_page[:results].first

    if saved_query[:is_compatible_with_api_version]
      # Create report job.
      report_job = {:report_query => saved_query[:report_query]}
    else
      raise StandardError, 'Report query is not compatible with the API'
    end
    

কোয়েরি রান করতে, ReportJob তৈরি করা দেখুন।

ReportQuery তৈরি করা

সেভ করা কোয়েরি ব্যবহার করার পাশাপাশি, আপনি অ্যাড হক ReportQuery তৈরি করতে পারেন। এটি করতে, আপনাকে অবশ্যই রিপোর্টের ডাইমেনশন, ডাইমেনশন অ্যাট্রিবিউট, কলাম, ফিল্টার এবং তারিখের রেঞ্জ সেট করতে হবে। এই উদাহরণটি একটি অর্ডারের জন্য প্রাথমিক ডেলিভারি রিপোর্টের জন্য।

Java

    // Create report query.
    ReportQuery reportQuery = new ReportQuery();
    reportQuery.setDimensions(new Dimension[] {Dimension.DATE, Dimension.ORDER_ID});
    reportQuery.setColumns(
        new Column[] {
          Column.AD_SERVER_IMPRESSIONS,
          Column.AD_SERVER_CLICKS,
          Column.AD_SERVER_CTR,
          Column.AD_SERVER_CPM_AND_CPC_REVENUE
        });
    reportQuery.setDimensionAttributes(
        new DimensionAttribute[] {
          DimensionAttribute.ORDER_TRAFFICKER,
          DimensionAttribute.ORDER_START_DATE_TIME,
          DimensionAttribute.ORDER_END_DATE_TIME
        });

    // Create statement to filter for an order.
    StatementBuilder statementBuilder =
        new StatementBuilder()
            .where("ORDER_ID = :orderId")
            .withBindVariableValue("orderId", orderId);

    // Set the filter statement.
    reportQuery.setStatement(statementBuilder.toStatement());

    // Set the start and end dates or choose a dynamic date range type.
    reportQuery.setDateRangeType(DateRangeType.CUSTOM_DATE);
    reportQuery.setStartDate(
        DateTimes.toDateTime("2013-05-01T00:00:00", "America/New_York").getDate());
    reportQuery.setEndDate(
        DateTimes.toDateTime("2013-05-31T00:00:00", "America/New_York").getDate());
    

Python

  # Create statement object to filter for an order.
  statement = (ad_manager.StatementBuilder(version='v202608')
               .Where('ORDER_ID = :id')
               .WithBindVariable('id', int(order_id))
               .Limit(None)  # No limit or offset for reports
               .Offset(None))

  # Set the start and end dates of the report to run (past 8 days).
  end_date = datetime.now().date()
  start_date = end_date - timedelta(days=8)

  # Create report job.
  report_job = {
      'reportQuery': {
          'dimensions': ['ORDER_ID', 'ORDER_NAME'],
          'dimensionAttributes': ['ORDER_TRAFFICKER', 'ORDER_START_DATE_TIME',
                                  'ORDER_END_DATE_TIME'],
          'statement': statement.ToStatement(),
          'columns': ['AD_SERVER_IMPRESSIONS', 'AD_SERVER_CLICKS',
                      'AD_SERVER_CTR', 'AD_SERVER_CPM_AND_CPC_REVENUE',
                      'AD_SERVER_WITHOUT_CPD_AVERAGE_ECPM'],
          'dateRangeType': 'CUSTOM_DATE',
          'startDate': start_date,
          'endDate': end_date
      }
  }
    

PHP

      // Create report query.
      $reportQuery = new ReportQuery();
      $reportQuery->setDimensions(
          [
              Dimension::ORDER_ID,
              Dimension::ORDER_NAME
          ]
      );
      $reportQuery->setDimensionAttributes(
          [
              DimensionAttribute::ORDER_TRAFFICKER,
              DimensionAttribute::ORDER_START_DATE_TIME,
              DimensionAttribute::ORDER_END_DATE_TIME
          ]
      );
      $reportQuery->setColumns(
          [
              Column::AD_SERVER_IMPRESSIONS,
              Column::AD_SERVER_CLICKS,
              Column::AD_SERVER_CTR,
              Column::AD_SERVER_CPM_AND_CPC_REVENUE,
              Column::AD_SERVER_WITHOUT_CPD_AVERAGE_ECPM
          ]
      );

      // Create statement to filter for an order.
      $statementBuilder = (new StatementBuilder())
          ->where('ORDER_ID = :orderId')
          ->withBindVariableValue(
              'orderId',
              $orderId
          );

      // Set the filter statement.
      $reportQuery->setStatement($statementBuilder->toStatement());

      // Set the start and end dates or choose a dynamic date range type.
      $reportQuery->setDateRangeType(DateRangeType::CUSTOM_DATE);
      $reportQuery->setStartDate(
          AdManagerDateTimes::fromDateTime(
              new DateTime(
                  '-10 days',
                  new DateTimeZone('America/New_York')
              )
          )
              ->getDate()
      );
      $reportQuery->setEndDate(
          AdManagerDateTimes::fromDateTime(
              new DateTime(
                  'now',
                  new DateTimeZone('America/New_York')
              )
          )
              ->getDate()
      );
    

C#

// Create report job.
ReportJob reportJob = new ReportJob();
reportJob.reportQuery = new ReportQuery();
reportJob.reportQuery.dimensions = new Dimension[]
{
    Dimension.ORDER_ID,
    Dimension.ORDER_NAME
};
reportJob.reportQuery.dimensionAttributes = new DimensionAttribute[]
{
    DimensionAttribute.ORDER_TRAFFICKER,
    DimensionAttribute.ORDER_START_DATE_TIME,
    DimensionAttribute.ORDER_END_DATE_TIME
};
reportJob.reportQuery.columns = new Column[]
{
    Column.AD_SERVER_IMPRESSIONS,
    Column.AD_SERVER_CLICKS,
    Column.AD_SERVER_CTR,
    Column.AD_SERVER_CPM_AND_CPC_REVENUE,
    Column.AD_SERVER_WITHOUT_CPD_AVERAGE_ECPM
};

// Set a custom date range for the last 8 days
reportJob.reportQuery.dateRangeType = DateRangeType.CUSTOM_DATE;
System.DateTime endDateTime = System.DateTime.Now;
reportJob.reportQuery.startDate = DateTimeUtilities
    .FromDateTime(endDateTime.AddDays(-8), "America/New_York").date;
reportJob.reportQuery.endDate = DateTimeUtilities
    .FromDateTime(endDateTime, "America/New_York").date;

// Create statement object to filter for an order.
StatementBuilder statementBuilder = new StatementBuilder().Where("ORDER_ID = :id")
    .AddValue("id", orderId);
reportJob.reportQuery.statement = statementBuilder.ToStatement();
    

Ruby

  # Specify a report to run for the last 7 days.
  report_end_date = ad_manager.today()
  report_start_date = report_end_date - 7

  # Create statement object to filter for an order.
  statement = ad_manager.new_report_statement_builder do |sb|
    sb.where = 'ORDER_ID = :order_id'
    sb.with_bind_variable('order_id', order_id)
  end

  # Create report query.
  report_query = {
    :date_range_type => 'CUSTOM_DATE',
    :start_date => report_start_date.to_h,
    :end_date => report_end_date.to_h,
    :dimensions => ['ORDER_ID', 'ORDER_NAME'],
    :dimension_attributes => ['ORDER_TRAFFICKER', 'ORDER_START_DATE_TIME',
        'ORDER_END_DATE_TIME'],
    :columns => ['AD_SERVER_IMPRESSIONS', 'AD_SERVER_CLICKS', 'AD_SERVER_CTR',
        'AD_SERVER_CPM_AND_CPC_REVENUE', 'AD_SERVER_WITHOUT_CPD_AVERAGE_ECPM'],
    :statement => statement.to_statement()
  }
    

ReportJob তৈরি করা হচ্ছে

আপনার কাছে ReportQuery থাকলে, এবার রিপোর্ট রান করার সময় হয়েছে। ReportJob অবজেক্ট রিপোর্টের স্ট্যাটাস ধরে রাখে এবং এটি ডাউনলোড করার জন্য রেডি হলে আপনাকে জানায়। আপনার রিপোর্ট চালানো শুরু করতে, ReportService.runReportJob পদ্ধতি ব্যবহার করুন।

Java

    // Create report job.
    ReportJob reportJob = new ReportJob();
    reportJob.setReportQuery(reportQuery);

    // Run report job.
    reportJob = reportService.runReportJob(reportJob);
    

Python

  # Initialize a DataDownloader.
  report_downloader = client.GetDataDownloader(version='v202608')

  try:
    # Run the report and wait for it to finish.
    report_job_id = report_downloader.WaitForReport(report_job)
  except errors.AdManagerReportError as e:
    print('Failed to generate report. Error was: %s' % e)
    

PHP

      // Create report job and start it.
      $reportJob = new ReportJob();
      $reportJob->setReportQuery($reportQuery);
      $reportJob = $reportService->runReportJob($reportJob);
    

C#

// Run report job.
reportJob = reportService.runReportJob(reportJob);
    

Ruby

  # Create report job.
  report_job = {:report_query => report_query}

  # Run report job.
  report_job = report_service.run_report_job(report_job);
    

রিপোর্ট ডাউনলোড করা হচ্ছে

রিপোর্ট জব শুরু করার পরে, সার্ভার দ্বারা সেট করা একটি আইডি এতে থাকবে। আপনার রিপোর্টের স্ট্যাটাস চেক করতে ReportService.getReportJobStatus পদ্ধতির সাথে এই আইডি ব্যবহার করুন। স্ট্যাটাস ReportJobStatus.COMPLETED হয়ে গেলে রিপোর্ট ডাউনলোড করার জন্য রেডি হয়ে যায়।

আমাদের কিছু ক্লায়েন্ট লাইব্রেরিতে সহায়ক ইউটিলিটি আছে যা API পোল করবে এবং রিপোর্ট সম্পূর্ণ হওয়ার জন্য অপেক্ষা করবে। রিপোর্ট তৈরি হয়ে গেলে, আপনি ReportService.getReportDownloadURL পদ্ধতির মাধ্যমে ডাউনলোড URL পেতে পারেন। রিপোর্ট বিভিন্ন ফর্ম্যাটে ডাউনলোড করা যেতে পারে। আপনি যদি রিপোর্টের সাথে আরও মেশিন প্রসেসিং করতে চান, তাহলে আপনার CSV_DUMP ফর্ম্যাট ব্যবহার করা উচিত।

Java

    // Create report downloader.
    ReportDownloader reportDownloader = new ReportDownloader(reportService, reportJob.getId());

    // Wait for the report to be ready.
    if (reportDownloader.waitForReportReady()) {
      // Change to your file location.
      File file = File.createTempFile("delivery-report-", ".csv.gz");

      System.out.printf("Downloading report to %s ...", file.toString());

      // Download the report.
      ReportDownloadOptions options = new ReportDownloadOptions();
      options.setExportFormat(ExportFormat.CSV_DUMP);
      options.setUseGzipCompression(true);
      URL url = reportDownloader.getDownloadUrl(options);
      Resources.asByteSource(url).copyTo(Files.asByteSink(file));

      System.out.println("done.");
    } else {
      System.out.printf("Report job %d failed.%n", reportJob.getId());
    }
    

Python

  # Change to your preferred export format.
  export_format = 'CSV_DUMP'

  report_file = tempfile.NamedTemporaryFile(suffix='.csv.gz', delete=False)

  # Download report data.
  report_downloader.DownloadReportToFile(
      report_job_id, export_format, report_file)

  report_file.close()

  # Display results.
  print('Report job with id "%s" downloaded to:\n%s' % (
      report_job_id, report_file.name))
    

PHP

      // Create report downloader to poll report's status and download when
      // ready.
      $reportDownloader = new ReportDownloader(
          $reportService,
          $reportJob->getId()
      );
      if ($reportDownloader->waitForReportToFinish()) {
          // Write to system temp directory by default.
          $filePath = sprintf(
              '%s.csv.gz',
              tempnam(sys_get_temp_dir(), 'delivery-report-')
          );
          printf("Downloading report to %s ...%s", $filePath, PHP_EOL);
          // Download the report.
          $reportDownloader->downloadReport(
              ExportFormat::CSV_DUMP,
              $filePath
          );
          print "done.\n";
      } else {
          print "Report failed.\n";
      }
    

C#

ReportUtilities reportUtilities =
    new ReportUtilities(reportService, reportJob.id);

// Set download options.
ReportDownloadOptions options = new ReportDownloadOptions();
options.exportFormat = ExportFormat.CSV_DUMP;
options.useGzipCompression = true;
reportUtilities.reportDownloadOptions = options;

// Download the report.
using (ReportResponse reportResponse = reportUtilities.GetResponse())
{
    reportResponse.Save(filePath);
}

Console.WriteLine("Report saved to \"{0}\".", filePath);
    

Ruby

  MAX_RETRIES.times do |retry_count|
    # Get the report job status.
    report_job_status = report_service.get_report_job_status(report_job[:id])

    break unless report_job_status == 'IN_PROGRESS'
    puts 'Report with ID %d is still running.' % report_job[:id]
    sleep(RETRY_INTERVAL)
  end

  puts 'Report job with ID %d finished with status "%s".' % [report_job[:id],
      report_service.get_report_job_status(report_job[:id])]

  # Get the report URL.
  download_url = report_service.get_report_download_url(
      report_job_id, export_format
  )

  puts 'Downloading "%s" to "%s"...' % [download_url, file_name]
  open(file_name, 'wb') do |local_file|
    local_file << URI.open(download_url).read()
  end
    

রিপোর্ট ডেটা পড়া

আমাদের অনেক ক্লায়েন্ট লাইব্রেরিতে রিপোর্ট ডেটা পড়ার জন্য ইউটিলিটি অন্তর্ভুক্ত থাকে। এটি রিপোর্ট ডেটার উপর অতিরিক্ত প্রসেসিং করার জন্য বা বিভিন্ন তারিখের রেঞ্জ থেকে রিপোর্ট একত্রিত করার জন্য উপযোগী। মনে রাখবেন, উদাহরণ কোডটি ধরে নেয় যে ফাইলটি কম্প্রেস করা হয়নি।

Java

  List<String[]> rows = CsvFiles.getCsvDataArray(filePath, true);
  for (String[] row : rows) {
    // Additional row processing
    processReportRow(row);
  }
    

Python

  with open(report_file.name, 'rb') as report:
    report_reader = csv.reader(report)
    for row in report_reader:
      # Additional row processing
      process_row(row)
    

PHP

  $report = fopen($filePath, 'r');
  while (!feof($report)) {
    // Additional row processing
    processRow(fgetcsv($report));
  }
  fclose($report);
    

C#

  CsvFile file = new CsvFile();
  file.Read(fileName, true);
  for (String[] row : file.Records) {
    // Additional row processing
    ProcessReportRow(row);
  }
    

Ruby

    CSV.foreach(file_name, converters: :numeric, headers: true) do |row|
      # Additional row processing
      process_row(row)
    end
    

রিপোর্টিংয়ের আরও উদাহরণের জন্য, GitHub-এ আমাদের ক্লায়েন্ট লাইব্রেরি চেক করুন।

প্রায়শই জিজ্ঞাসিত প্রশ্ন

আমার টেস্ট নেটওয়ার্কে সব রিপোর্টের ফলাফল খালি কেন?
টেস্ট নেটওয়ার্ক বিজ্ঞাপন দেখায় না, তাই ডেলিভারি রিপোর্টে কোনও ডেটা থাকবে না।
আমার প্রোডাকশন নেটওয়ার্কে সব রিপোর্টের ফলাফল খালি কেন?
আপনি যে ব্যবহারকারী হিসেবে যাচাই করছেন, তার কাছে হয়ত সেই ডেটার অ্যাক্সেস নেই, যে ডেটার উপর আপনি রিপোর্ট করার চেষ্টা করছেন। তাদের ভূমিকার অনুমতি এবং টিম সঠিকভাবে সেট করা আছে কিনা তা যাচাই করুন।
আমার রিপোর্টের জন্য আমি কেন ReportError.COLUMNS_NOT_SUPPORTED_FOR_REQUESTED_DIMENSIONS সমস্যা সংক্রান্ত মেসেজ পাই?
Ad Manager-এ কলাম ও ডাইমেনশনের সব কম্বিনেশন কাজ করে না। জটিল রিপোর্টের ক্ষেত্রে, UI-তে একটি সঠিক রিপোর্ট তৈরি করা এবং তারপরে ReportService.getSavedQueriesByStatement পদ্ধতির মাধ্যমে এটি উদ্ধার করা সহজ হতে পারে।
আমার সেভ করা রিপোর্ট API-তে কেন ফেরত দেওয়া হয়নি?
নিশ্চিত করুন যে রিপোর্টের মালিক সেই ব্যবহারকারীর সাথে রিপোর্ট শেয়ার করেছেন যার হয়ে আপনি যাচাই করছেন।
আমার সেভ করা রিপোর্ট API-এর সাথে মানানসই নয় কেন?
API-তে নির্দিষ্ট কিছু রিপোর্টিং ফিচার উপলভ্য নেই। এর মধ্যে কলাম, ডাইমেনশন অ্যাট্রিবিউট, ডাইমেনশন ও তারিখের ব্যাপ্তির ধরন অন্তর্ভুক্ত। তারিখের রেঞ্জের ধরন অসঙ্গত হলে, আপনি রিপোর্টটি একটি কাজ করে এমন ধরনের সাথে সেভ করতে পারেন যাতে এটি পুনরুদ্ধারযোগ্য হয়, তারপর আপনার পছন্দসই নির্দিষ্ট তারিখের রেঞ্জ পূরণ করতে ReportQuery পরিবর্তন করুন।
লাইফটাইম ক্লিক/ইম্প্রেশন UI-তে আমার রিপোর্টের সাথে কেন মিলছে না?
লাইফটাইম ইম্প্রেশন হল রিপোর্টের তারিখের ব্যাপ্তি যাই হোক না কেন, লাইন আইটেমের সম্পূর্ণ লাইফটাইমের জন্য। কোনও লাইন আইটেম এখনও ডেলিভার করা হলে, যেকোনও দুটি রিপোর্ট রান করার মধ্যে সম্ভবত ভ্যালু পরিবর্তন হবে।
আমার রিপোর্ট তৈরি হতে অনেক সময় লাগছে এবং মাঝে মাঝে টাইম-আউট হয়ে যাচ্ছে। আমি কী করতে পারি?
তারিখের রেঞ্জ বা ডাইমেনশনের সংখ্যা কমালে পারফর্ম্যান্স উন্নত করতে সাহায্য করবে। পরিবর্তে, ছোট তারিখের রেঞ্জের জন্য একাধিক রিপোর্ট রান করে দেখুন। আপনি তারপরে কাঙ্খিত তারিখের ব্যাপ্তি কভার করতে রিপোর্টের ডেটা মার্জ করতে পারবেন।
INVENTORY_LEVEL এবং LINE_ITEM_LEVEL কলামের মধ্যে পার্থক্য কী? আমি কোনটি ব্যবহার করব?

LINE_ITEM_LEVEL সহ কলাম তখনই ব্যবহার করা যাবে যখন আপনার নেটওয়ার্কে লাইন আইটেম লেভেল ডায়নামিক অ্যালোকেশন চালু করা থাকবে। এই কলামে AdSense বা Ad Exchange-এ লাইন আইটেম লেভেল ডায়নামিক অ্যালোকেশন থেকে পাওয়া ডেটা অন্তর্ভুক্ত থাকে। একইভাবে, INVENTORY_LEVEL কলামে ইনভেনটরি লেভেল ডায়নামিক অ্যালোকেশন থেকে পাওয়া ডেটা অন্তর্ভুক্ত থাকে। ডায়নামিক অ্যালোকেশন সম্পর্কে আরও জানতে, Ad Exchange লাইন আইটেম দেখুন।

কোন API কলাম ব্যবহার করবেন তা এখনও বুঝতে না পারলে, Ad Manager UI-তে সেভ করা কোয়েরি তৈরি করুন এবং ReportService.getSavedQueriesByStatement পদ্ধতির মাধ্যমে এটি ফিরিয়ে আনুন।