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

Java 如何正确迭代所有BigQuery结果行?,java,google-api,google-bigquery,Java,Google Api,Google Bigquery,我正在从BigQuery表中选择一列,如 select url from `project.dataset.urllist` where status = 2 计数(*)会给出245217个结果,我可以在 浏览器控制台 根据上的示例在Java中实现相同的 看起来像 QueryResponse response = bigquery.query(queryRequest); QueryResult result = response.getResult(); while (result !=

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

select url from `project.dataset.urllist` where status = 2
计数(*)会给出245217个结果,我可以在 浏览器控制台

根据上的示例在Java中实现相同的 看起来像

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

while (result != null) {
  for (List<FieldValue> row : result.iterateAll()) {
    ... do something
  }
  result = result.getNextPage();
}
QueryResponse response=bigquery.query(queryRequest);
QueryResult result=response.getResult();
while(结果!=null){
for(列表行:result.iterateAll()){
…做点什么
}
result=result.getNextPage();
}
然而,我最终得到了从3个QueryResult页面返回的435651个结果行

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

QueryResult result = response.getResult();
for (List<FieldValue> row : result.iterateAll()) {
  ... do something
}
QueryResult result=response.getResult();
for(列表行:result.iterateAll()){
…做点什么
}
显然,第一个结果页包含从#1到#245217的所有行, 第二页包含从#100000到#245217的行, 第三页包含从#200000到#245217的行。
这是API中的一个Bug吗?

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

  • 只需依赖当前版本的Google Cloud Java Client Core(1.4.0)和BigQuery(0.22.0-beta)中的
    QueryResult#iteral()
    ;并在结果页中删除该外部循环

考虑 让我们看看
iterateAll
方法的实现,该方法由
QueryResult
com.google.cloud.PageImpl
继承。当前,此方法返回一个迭代器,该迭代器从当前页面开始,并且似乎在当前页面的所有元素都被迭代后获取下一个页面()。这在相应的
computeNext()
调用时发生,其中
currentPage=currentPage.getNextPage()显式出现

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

鉴于上述情况,通过页面将
result.iterateAll()
调用包装到附加循环中是多余的,因此看起来不是100%一致的,需要删除周围的循环

while (result != null) {
  ...
  result = result.getNextPage();
}
就API本身的一致性而言,缺乏明确的方法来处理每页的结果,因为对于特定页面上的特定行,我们既没有
iterateAll
的替代方法,也没有能力清楚地识别当前页面的末尾(除了在迭代时手动计数行的能力). 但是,当处理所有行的整个结果时,这似乎不是一个拦截器

编辑 请注意,在撰写本文之时,它处于测试阶段,并且有明确的说明:

注意:此客户端是一个正在进行的工作,有时可能会进行向后不兼容的更改

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

for
QueryResult
中的奇怪语言:
为所有值返回一个迭代器,也可能在接下来的页面中返回