Разбиение на страницы с токеном в клиенте BigQuery + PHP не работает

Я пытаюсь реализовать простой механизм разбиения на страницы с 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 результатов). Но когда я позже вызываю функцию с полученным токеном, результаты становятся пустыми … Я не знаю почему. Я не вижу сообщения об ошибке в журналах или что-нибудь …

0

Решение

Для того чтобы BigQuery «разбил на страницы», вы должны выполнить следующие шаги (упрощенно, но достаточно для этого ответа):

  1. Выполнить запрос
  2. Получить работу
  3. Выполните getQueryResults с этим идентификатором задания и получите результат и page_token
  4. Если page_token null — вы сделали, иначе переходите к следующему шагу
  5. Выполнить getQueryResults (still with jobid from #2) и получить результат и page_token
  6. Перейти к шагу № 4

Теперь вы, скорее всего, увидите, что ваш код не следует этому и каждый раз выполняет запрос как новое задание, что полностью нарушает условие, выделенное в # 5 (still with jobid from #2).

Причина, по которой в первый раз он возвращает результат, состоит в том, что первый вызов фактически соответствует вышеуказанным шагам, но при последовательных вызовах вы фактически передаете page_token и принудительно выполняете задание NEW с некоторым произвольным (из этого нового предполагаемого задания) page_token
А также, это объясняет, почему ваш текущий код работает с startIndex

Попробуйте переписать свой код, чтобы выполнить вышеуказанные шаги, и он должен работать

Также,
Постскриптум page_token активен и должен использоваться повторно до тех пор, пока базовая временная таблица (которая содержит ваш результат) активна — что составляет приблизительно 24 часа

1

Другие решения

Решил с помощью startIndex вместо токенов.

Может быть, токены недолговечны и не выдерживают 4-5 секундную задержку, я не совсем уверен.

0

Рекомендуется использовать маркер страницы для получения постраничных результатов, поскольку маркер страницы обеспечивает представление таблицы при первом получении. Просто используя startIndex, вы можете увидеть разные результаты, так как таблица может измениться.

Размер ответа — это то, что может привести к тому, что вы получите меньше, чем maxResults. Мы ограничены пасекой, чтобы вернуть результаты определенного размера.
https://cloud.google.com/bigquery/docs/data#paging
И у нас также есть максимальное число полей, которое должно быть меньше 350 000 лимитов на вызов.

Вы должны попытаться получить следующие результаты, используя маркер страницы, который он вам передал.

0

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>";
}

}

Это работает для меня … Надеюсь, вы можете построить вокруг этого

-2
По вопросам рекламы [email protected]