在BigQuery + PHP客户端中使用令牌分页无法正常工作

时间:2016-03-27 09:29:32

标签: php google-bigquery

我正在尝试使用BigQuery实现一个简单的分页机制。

这是我的查询功能:

function query($sql, $max_results = null, $page_token = null) {
    $request = new Google_Service_Bigquery_QueryRequest();
    $request->setQuery($sql);
    $response = $this->service->jobs->query(PROJECT_ID, $request);
    $job_id = $response->getJobReference()->getJobId();

    $optParams = ($max_results) ? array(
        'pageToken' => $page_token,
        'maxResults' => $max_results,
    ) : array();
    $response = $this->service->jobs->getQueryResults(PROJECT_ID, $job_id, $optParams);
    if (!$response->getJobComplete()) {
        return null;
    }
    $rowsJson = $this->rowsJson($response->getRows());
    if ($max_results) {
        return array(
            "rows" => $rowsJson,
            "token" => $response->getPageToken()
        );
    }
    return $rowsJson;
}

query("select url, CEIL(AVG(total)) as avg, count(id) as count from $table_id " .
      "where created > $date_start and created < $date_end group by url order by $order_by desc",
      10, $page_token
);

第一个查询似乎正在运行。它只返回10个结果和一个标记(肯定有超过10个结果)。但是当我稍后用我得到的令牌调用该函数时,结果是空的......我不知道为什么。我在日志或其他任何内容中看不到任何错误消息......

4 个答案:

答案 0 :(得分:1)

为了让BigQuery“分页”工作,请按照以下步骤进行操作(简化但足以满足此答案):

  1. 执行查询作业
  2. 检索jobid
  3. 使用该jobid执行getQueryResults并检索结果和page_token
  4. 如果page_token为null - 您已完成,否则继续下一步
  5. 执行getQueryResults(still with jobid from #2)并检索结果和page_token
  6. 跳到第4步
  7. 现在,您很可能会看到您的代码不遵循此规则,并且每次都将查询作为新作业执行 - 这完全打破了#5(still with jobid from #2)中突出显示的条件。

    第一次返回结果的原因是第一次调用实际上遇到了上述步骤,但是在连续调用中你实际上传递了page_token并强制执行了一些任意的新作业(来自那个新的工作)page_token
    而且,这也解释了为什么您当前的代码适用于startIndex

    尝试重写代码以遵循上述步骤,它应该可以正常工作

    另外,
    附: page_token是活着的,只要基础临时表(保存你的结果)还活着 - 大约24小时

    ,它就应该是可重用的

答案 1 :(得分:0)

使用startIndex代替令牌解决了这个问题。

也许令牌是短暂的,并且在4-5秒的延迟中无法存活,我不太确定。

答案 2 :(得分:0)

建议使用页面标记获取分页结果,因为页面标记在第一次检索时提供了表格视图。通过使用startIndex,您可能会看到不同的结果,因为表可能会更改。

响应大小可能会导致您获得小于maxResults。我们被Apiary限制返回一定规模的结果。 https://cloud.google.com/bigquery/docs/data#paging 我们还有一个最大字段数量,每次呼叫的限制小于350,000。

您应该尝试使用传回给您的页面标记来获取下一个结果。

答案 3 :(得分:-2)

function get_quote($page = 1){
global $database_connection;
    $start = 0;
    $limit = 5;
    $start = ($page - 1) * $limit;

    //select from database with limit $start, $limit
    //display results

    $sql_get_quote =  "SELECT * FROM quote_table ORDER BY date_added ASC LIMIT $start, $limit";
    $query_get_quote = mysqli_query($database_connection, $sql_get_quote);
    while($fetch_quote = mysqli_fetch_array($query_get_quote)){
        echo "<br>
        <div class='w3-container w3-pale-green w3-bottombar w3-border-green w3-border'>
        <p>".$fetch_quote['quote']."</p><hr><p class='w3-left-align'>".$fetch_quote['quote_by']."</p>
        </div>";
    }

    //do another query, get the num_rows
    $quote_rows= mysqli_num_rows (mysqli_query($database_connection ,"SELECT * FROM quote_table"));
    $total = ceil($quote_rows / $limit);
if (isset($page)){
    echo "<div class='w3-container'>";
    echo "<ul class='pager'>";
    if($page > 1) {
        echo "<a href='?page=".($page - 1)."' style='float: left;' class=' w3-sand w3-btn w3-margin w3-round'>Previous</a>";
    }
    for($i = 1; $i <= $total; $i++) {
        if($i == $page) { echo "<li class='active current'>".$i."</li>"; }

        else { echo "<li><a href='?page=".$i."'>".$i."</a></li>"; }
    }
    if($page != $total) {
        echo "<a href='?page=".($page + 1)."' class='w3-btn w3-margin w3-sand w3-round'>Next</a>";
    }
    echo "</ul></div>";
}

}

这对我有用......希望你能围绕这个

进行构建