java - 如何正确迭代所有 BigQuery 结果行?

标签 java google-api google-bigquery

我正在从 BigQuery 表中选择一列,例如

select url from `project.dataset.urllist` where status = 2

count(*) 给出了 245217 个结果,我可以在 浏览器控制台。

根据示例在 Java 中实现相同的 https://cloud.google.com/bigquery/create-simple-app-api看起来像

QueryResponse response = bigquery.query(queryRequest);
QueryResult result = response.getResult();

while (result != null) {
  for (List<FieldValue> row : result.iterateAll()) {
    ... do something
  }
  result = result.getNextPage();
}

但是我最终从 3 个 QueryResult 页面返回了 435651 个结果行。

我发现在 while 循环的第一次迭代中我已经得到 所需的 245217 行;第二次和第三次迭代返回一部分 同样的结果。 如果没有 while 循环,我会收到我期望的结果,但这是正确的吗?

QueryResult result = response.getResult();
for (List<FieldValue> row : result.iterateAll()) {
  ... do something
}

显然,第一个结果页面包含从 #1 到 #245217 的所有行, 第二页包含从 #100000 到 #245217 的行, 第三页包含从 #200000 到 #245217 的行。 这是 API 中的错误吗?

最佳答案

从实用的角度来看,关于如何正确迭代所有 BigQuery 行的简短答案似乎是:

  • 仅依赖当前版本的 Google Cloud Java Client Core (1.4.0) 和 BigQuery (0.22.0-beta) 中的 QueryResult#iterateAll();并通过结果页面删除该外部循环。

考虑

让我们看一下 iterateAll 方法的实现,该方法由 QueryResultcom.google.cloud.PageImpl 继承。目前,此方法返回一个 Iterator,它从当前页面开始,一旦当前页面的所有元素都被迭代(github link),它似乎会获取下一页。这发生在相应的 computeNext() 调用时,其中 currentPage = currentPage.getNextPage(); 显式发生

也就是说,result.getNextPage().iterateAll() 返回迭代器,它从 getNextPage 返回的页面的第一个元素开始迭代元素,并将迭代所有下一页,直到到达最后一页的最后一个元素。与 result.iterateAll() 的唯一区别是最后一个返回从第一页开始的迭代器。

根据以上所述,将 result.iterateAll() 调用包装到页面的附加循环中是多余的,所以看起来像 current version of example不是 100% 一致的,需要删除周围的循环

while (result != null) {
  ...
  result = result.getNextPage();
}

就 API 本身的一致性而言 - 缺乏明确的方法来处理每页的结果,因为对于特定页面上的特定行,我们既没有替代 iterateAll 的方法,也无法清楚地识别已到达当前页面的末尾(除了能够在迭代时手动计算行数)。但是,当处理所有行的整个结果时 - 这似乎不是一个障碍

编辑

请注意Java Client for BigQuery在撰写本文时处于测试阶段,并且明确指出:

Note: This client is a work-in-progress, and may occasionally make backwards-incompatible changes.

这意味着我们应该期待进一步的变化并相应地调整处理所有行的方法。

关于java - 如何正确迭代所有 BigQuery 结果行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45880362/

相关文章:

java - 在 Solaris 操作系统中使用 Java 和第 3 方库在打印机中打印 PDF

authentication - 使用 Google Storage Transfer API 将数据从外部 GCS 传输到我的 GCS

google-analytics - Google Analytics(分析)数据集从头开始重新启动

mysql - 将数据从 MySQL 复制到 Google BigQuery

java - Apache Beam - BigQueryIO 读取投影

java - 将 Jsch 0.1.42 升级到 0.1.54 会产生与远程服务器的连接超时

java - 模式匹配来检测单词中的特殊字符

java - 当我运行这个小鼠标钩子(Hook)应用程序时,为什么我的鼠标出现滞后?

javascript - 日历审核事件中的 Google Admin SDK

java - 通过 API 从 Android Pay 获取交易历史记录?