Как запросить результаты запроса BigQuery с разбивкой на страницы с помощью pageTokens с библиотекой Google Client для Java?

Я хочу выполнять запросы BigQuery с тысячами строк общих результатов, но я хочу получать только страницу со 100 результатами за раз (с использованием параметров maxResults и pageToken).

API BigQuery поддерживает использование pageToken параметров в collection.list методах. Однако я выполняю асинхронные запросы и получаю результаты с помощью метода getQueryResult, и, похоже, он не поддерживает параметр pageToken. Можно ли использовать pageTokens с getQueryResults?


person Michael Manoochehri    schedule 11.02.2013    source источник
comment
Как мы обрабатываем это в javascript. Я пытаюсь сделать это в javascript, но ничего не нашел в документации. Любая помощь будет принята с благодарностью.   -  person Innovation    schedule 05.03.2014


Ответы (1)


Обновление: появилась новая документация о том, как пролистать список результатов здесь < / а>.

Я отвечаю на этот вопрос самостоятельно, потому что разработчик задал мне это лично, и я хочу поделиться ответом на Stack Overflow.

Параметр pageToken доступен для использования при запросе результатов с разбивкой на страницы из метода Tabledata.list. Наборы результатов разбиваются на страницы автоматически, когда, например, данные результата превышают 100 тыс. Строк или 10 МБ результатов. Вы также можете запросить разбиение на страницы результатов, явно задав параметр maxResults. Каждая страница результатов будет возвращать параметр pageToken, который затем можно использовать для получения следующей страницы результатов.

Каждый запрос приводит к созданию новой таблицы BigQuery. Если вы не укажете имя таблицы явно, она будет длиться всего 24 часа. Однако даже безымянные «анонимные» таблицы имеют идентификатор. В любом случае после вставки задания запроса получите имя вновь созданной таблицы. Затем используйте метод tabledata.list (и комбинацию параметров maxResults / pageToken) для запроса результатов в форме с разбивкой на страницы. Выполните цикл и продолжайте вызывать tabledata.list, используя ранее полученный pageToken, пока не перестанут возвращаться pageTokens (это означает, что вы достигли последней страницы.

При использовании клиентской библиотеки Google API для Java код для вставки задания запроса, опроса на предмет завершения запроса и последующего получения страницы за страницей результатов запроса может выглядеть примерно так:

// Create a new BigQuery client authorized via OAuth 2.0 protocol
// See: https://developers.google.com/bigquery/docs/authorization#installed-applications
Bigquery bigquery = createAuthorizedClient();

// Start a Query Job
String querySql = "SELECT TOP(word, 500), COUNT(*) FROM publicdata:samples.shakespeare";
JobReference jobId = startQuery(bigquery, PROJECT_ID, querySql);

// Poll for Query Results, return result output
TableReference completedJob = checkQueryResults(bigquery, PROJECT_ID, jobId);

// Return and display the results of the Query Job
displayQueryResults(bigquery, completedJob);

/**
 * Inserts a Query Job for a particular query
 */
public static JobReference startQuery(Bigquery bigquery, String projectId,
                                      String querySql) throws IOException {
  System.out.format("\nInserting Query Job: %s\n", querySql);

  Job job = new Job();
  JobConfiguration config = new JobConfiguration();
  JobConfigurationQuery queryConfig = new JobConfigurationQuery();
  config.setQuery(queryConfig);

  job.setConfiguration(config);
  queryConfig.setQuery(querySql);

  Insert insert = bigquery.jobs().insert(projectId, job);
  insert.setProjectId(projectId);
  JobReference jobId = insert.execute().getJobReference();

  System.out.format("\nJob ID of Query Job is: %s\n", jobId.getJobId());

  return jobId;
}

/**
 * Polls the status of a BigQuery job, returns TableReference to results if "DONE"
 */
private static TableReference checkQueryResults(Bigquery bigquery, String projectId, JobReference jobId)
    throws IOException, InterruptedException {
  // Variables to keep track of total query time
  long startTime = System.currentTimeMillis();
  long elapsedTime;

  while (true) {
    Job pollJob = bigquery.jobs().get(projectId, jobId.getJobId()).execute();
    elapsedTime = System.currentTimeMillis() - startTime;
    System.out.format("Job status (%dms) %s: %s\n", elapsedTime,
        jobId.getJobId(), pollJob.getStatus().getState());
    if (pollJob.getStatus().getState().equals("DONE")) {
      return pollJob.getConfiguration().getQuery().getDestinationTable();
    }
    // Pause execution for one second before polling job status again, to
    // reduce unnecessary calls to the BigQUery API and lower overall
    // application bandwidth.
    Thread.sleep(1000);
  }
}

/**
 * Page through the result set
 */
private static void displayQueryResults(Bigquery bigquery,
                                        TableReference completedJob) throws IOException {

    long maxResults = 20;
    String pageToken = null;
    int page = 1;

  // Default to not looping
    boolean moreResults = false;

    do {
    TableDataList queryResult = bigquery.tabledata().list(
            completedJob.getProjectId(),
            completedJob.getDatasetId(),
            completedJob.getTableId())
                .setMaxResults(maxResults)
                .setPageToken(pageToken)
         .execute();
    List<TableRow> rows = queryResult.getRows();
    System.out.print("\nQuery Results, Page #" + page + ":\n------------\n");
    for (TableRow row : rows) {
      for (TableCell field : row.getF()) {
      System.out.printf("%-50s", field.getV());
       }
      System.out.println();
    }
    if (queryResult.getPageToken() != null) {
      pageToken = queryResult.getPageToken();
      moreResults = true;
      page++;
    } else {
      moreResults = false;
    }
  } while (moreResults);
}
person Michael Manoochehri    schedule 11.02.2013
comment
Почему моя работа не дает мне целевого стола? - person Tjorriemorrie; 13.10.2014
comment
похоже, что API снова изменился, и Google не обновлял его с версии 0.3, в то время как новая версия около 1.2 как мне получить следующую страницу в новой версии? - person 2Big2BeSmall; 19.11.2017