Grundlegendes zu Berichten

Einführung

In diesem Leitfaden erfahren Sie, wie Sie einen Bericht mit der API erstellen und herunterladen. Sie erfahren, wie Sie eine vorhandene gespeicherte Berichtsabfrage verwenden und eine Ad-hoc-Berichtabfrage erstellen.

Voraussetzungen

Primer

Falls Sie mit der Berichterstellung in Ad Manager nicht vertraut sind, erhalten Sie unter Neuen Bericht erstellen eine Übersicht darüber, wie ein Bericht auf der Ad Manager-Benutzeroberfläche generiert wird. Auf der Benutzeroberfläche werden eine Vorschau der Ausgabe sowie Kurzinfos angezeigt, in denen erläutert wird, welche Kombinationen aus Spalten und Dimensionen unterstützt werden. Wenn Sie eine komplexe Berichtsabfrage erstellen, ist es möglicherweise einfacher, diese zuerst in der Benutzeroberfläche zu erstellen und dann mit der API abzurufen.

Eine gespeicherte ReportQuery abrufen

Das Objekt ReportQuery enthält alle Details des Berichts. Sie können Berichtsabfragen in der Ad Manager-Benutzeroberfläche erstellen und mit der Methode ReportService.getSavedQueriesByStatement abrufen. Die gespeicherte Abfrage-ID ist beim Aufrufen einer Abfrage auf der Benutzeroberfläche in der URL enthalten. In der URL https://www.google.com/admanager/1234#reports/report/detail/report_id=456789 lautet die Abfrage-ID beispielsweise 456789.

Ist eine Abfrage nicht mit Ihrer API-Version kompatibel, ist SavedQuery.reportQuery auf null und SavedQuery.isCompatibleWithApiVersion false.

Kompatible gespeicherte Abfragen können mit oder ohne Änderung ausgeführt werden.

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='v202402')
               .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
    

Informationen zum Ausführen der Abfrage finden Sie unter ReportJob erstellen.

ReportQuery erstellen

Neben der Verwendung gespeicherter Abfragen können Sie auch eine Ad-hoc-ReportQuery erstellen. Dazu müssen Sie die Dimensionen, Dimensionsattribute, Spalten, Filter und Zeiträume des Berichts festlegen. Dieses Beispiel bezieht sich auf einen einfachen Bericht zur Anzeigenauslieferung für eine einzelne Bestellung.

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='v202402')
               .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 erstellen

Sobald eine ReportQuery erstellt wurde, können Sie den Bericht erstellen. Das Objekt ReportJob enthält den Status eines Berichts und informiert Sie, wenn der Bericht heruntergeladen werden kann. Verwenden Sie zum Erstellen des Berichts die Methode 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='v202402')

  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);
    

Bericht herunterladen

Nachdem Sie den Berichtauftrag gestartet haben, wird vom Server eine ID festgelegt. Verwenden Sie diese ID mit der Methode ReportService.getReportJobStatus, um den Status Ihres Berichts zu prüfen. Sobald der Status ReportJobStatus.COMPLETED lautet, kann der Bericht heruntergeladen werden.

Einige unserer Clientbibliotheken enthalten Hilfsdienstprogramme, die die API abfragen und warten, bis der Bericht fertig ist. Wenn der Bericht fertig ist, können Sie die Download-URL mit der Methode ReportService.getReportDownloadURL abrufen. Berichte können in verschiedenen Formaten heruntergeladen werden. Wenn Sie den Bericht weiter maschinell verarbeiten möchten, sollten Sie das CSV_DUMP-Format verwenden.

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 << open(download_url).read()
  end
    

Lesen der Berichtsdaten

Viele unserer Clientbibliotheken enthalten Dienstprogramme zum Lesen von Berichtsdaten. Dies ist nützlich, um die Berichtsdaten weiter zu verarbeiten oder Berichte aus verschiedenen Zeiträumen zu kombinieren. Im Beispielcode wird davon ausgegangen, dass die Datei nicht komprimiert ist.

Java


  List 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
    

Weitere Beispiele für Berichte finden Sie in unseren Clientbibliotheken auf GitHub.

Häufig gestellte Fragen

Warum sind alle Berichtsergebnisse in meinem Testnetzwerk leer?
In Testnetzwerken werden keine Anzeigen ausgeliefert, sodass Berichte zur Auslieferung keine Daten enthalten.
Warum sind alle Berichtsergebnisse in meinem Produktionsnetzwerk leer?
Der Nutzer, als der Sie sich authentifizieren, hat möglicherweise keinen Zugriff auf die Daten, für die Sie einen Bericht erstellen möchten. Prüfen Sie, ob die Rollenberechtigungen und Teams der Nutzer korrekt festgelegt sind.
Warum erhalte ich für meinen Bericht den Fehler ReportError.COLUMNS_NOT_SUPPORTED_FOR_REQUESTED_DIMENSIONS?
In Ad Manager werden nicht alle Kombinationen aus Spalten und Dimensionen unterstützt. Bei komplexen Berichten ist es möglicherweise einfacher, einen gültigen Bericht in der Benutzeroberfläche zu erstellen und ihn dann mit der Methode ReportService.getSavedQueriesByStatement abzurufen.
Warum wird mein gespeicherter Bericht nicht in der API zurückgegeben?
Achten Sie darauf, dass der Inhaber des Berichts den Bericht für den Nutzer freigegeben hat, mit dem Sie sich authentifizieren.
Warum ist mein gespeicherter Bericht nicht mit der API kompatibel?
Bestimmte Berichtsfunktionen sind in der API nicht verfügbar. Dazu gehören Spalten, Dimensionsattribute, Dimensionen und Zeitraumtypen. Bei nicht kompatiblen Zeitraumtypen können Sie den Bericht mit einem unterstützten Typ speichern, damit er abgerufen werden kann, und dann ReportQuery so ändern, dass er dem gewünschten festen Zeitraum entspricht.
Warum stimmt die Gesamtzahl der Klicks/Impressionen nicht mit meinem Bericht in der Benutzeroberfläche überein?
Lifetime-Impressionen gelten für die gesamte Laufzeit der Werbebuchung, unabhängig vom Zeitraum des Berichts. Wenn eine Werbebuchung noch ausgeliefert wird, ändert sich der Wert wahrscheinlich zwischen zwei beliebigen Berichten.
Meine Berichte dauern zu lange und es kommt gelegentlich zu einer Zeitüberschreitung. What can I do?
Wenn Sie den Zeitraum oder die Anzahl der Dimensionen verringern, lässt sich die Leistung verbessern. Erstellen Sie stattdessen mehrere Berichte für kürzere Zeiträume. Anschließend können Sie die Berichtsdaten zusammenführen, um den gewünschten Zeitraum abzudecken.
Was ist der Unterschied zwischen den Spalten INVENTORY_LEVEL und LINE_ITEM_LEVEL? Welche soll ich verwenden?

Spalten mit LINE_ITEM_LEVEL können nur verwendet werden, wenn in Ihrem Netzwerk die dynamische Zuordnung auf Werbebuchungsebene aktiviert ist. Diese Spalten enthalten Daten aus der dynamischen Zuordnung auf Werbebuchungsebene zu AdSense oder Ad Exchange. Ebenso enthalten die INVENTORY_LEVEL-Spalten Daten aus der dynamischen Zuordnung auf Inventarebene. Weitere Informationen zur dynamischen Zuordnung finden Sie im Artikel Ad Exchange-Werbebuchungen.

Wenn Sie immer noch nicht sicher sind, welche API-Spalten Sie verwenden sollen, erstellen Sie auf der Ad Manager-Benutzeroberfläche eine gespeicherte Abfrage und rufen Sie diese mit der Methode ReportService.getSavedQueriesByStatement ab.