直接且简单,我使用Google Cloud Datastore Node.js API具有以下功能:
fetchAll(query, result=[], queryCursor=null) {
this.debug(`datastoreService.fetchAll, queryCursor=${queryCursor}`);
if (queryCursor !== null) {
query.start(queryCursor);
}
return this.datastore.runQuery(query)
.then( (results) => {
result=result.concat(results[0]);
if (results[1].moreResults === _datastore.NO_MORE_RESULTS) {
return result;
} else {
this.debug(`results[1] = `, results[1]);
this.debug(`fetch next with queryCursor=${results[1].endCursor}`);
return this.fetchAll(query, result, results[1].endCursor);
}
});
}
数据存储区API对象位于变量this.datastore
;
此功能的目标是获取给定查询的所有结果,尽管对每个runQuery
次呼叫返回的项目数量有任何限制。
我还没有发现Datastore API对此有任何明确的硬性限制,文档在这一点上似乎有点不透明,但我只注意到我始终获取
results[1] = { moreResults: 'MORE_RESULTS_AFTER_LIMIT' }
,
表示还有更多结果要提取,results[1].endCursor
仍然停留在每次迭代时再次传递的常量值。
因此,考虑到我插入此函数的一些简单查询,我只是继续迭代地运行查询,将查询开始游标(通过执行query.start(queryCursor);
)设置为结果中获得的endCursor
上一个查询。显然,我希望在此迭代中获得每个连续查询的下一组结果。但我总是得到results[1].endCursor
的相同值。我的问题是:为什么?
从概念上讲,我看不出与this example given in the Google Documentation的区别:
// By default, google-cloud-node will automatically paginate through all of
// the results that match a query. However, this sample implements manual
// pagination using limits and cursor tokens.
function runPageQuery (pageCursor) {
let query = datastore.createQuery('Task')
.limit(pageSize);
if (pageCursor) {
query = query.start(pageCursor);
}
return datastore.runQuery(query)
.then((results) => {
const entities = results[0];
const info = results[1];
if (info.moreResults !== Datastore.NO_MORE_RESULTS) {
// If there are more results to retrieve, the end cursor is
// automatically set on `info`. To get this value directly, access
// the `endCursor` property.
return runPageQuery(info.endCursor)
.then((results) => {
// Concatenate entities
results[0] = entities.concat(results[0]);
return results;
});
}
return [entities, info];
});
}
(除了事实,我没有自己指定查询结果大小的限制,我也试过,通过将其设置为1000,这不会改变任何东西。)
为什么我的代码遇到了这个无限循环,卡在每一步同时" endCursor"?我该如何纠正这个?
此外,datastore.runQuery()
每次通话获得的结果数量的硬限制是多少?到目前为止,我还没有在Google Datastore文档中找到此信息。
感谢。
答案 0 :(得分:4)
查看Datastore的Node.js客户端库的API documentation,该页面上有一个标题为“Paginating Records”的部分可能会对您有所帮助。以下是该部分代码段的直接副本:
var express = require('express');
var app = express();
var NUM_RESULTS_PER_PAGE = 15;
app.get('/contacts', function(req, res) {
var query = datastore.createQuery('Contacts')
.limit(NUM_RESULTS_PER_PAGE);
if (req.query.nextPageCursor) {
query.start(req.query.nextPageCursor);
}
datastore.runQuery(query, function(err, entities, info) {
if (err) {
// Error handling omitted.
return;
}
// Respond to the front end with the contacts and the cursoring token
// from the query we just ran.
var frontEndResponse = {
contacts: entities
};
// Check if more results may exist.
if (info.moreResults !== datastore.NO_MORE_RESULTS) {
frontEndResponse.nextPageCursor = info.endCursor;
}
res.render('contacts', frontEndResponse);
});
});
也许您可以尝试使用其他语法选项之一(而不是Promises)。 runQuery方法可以将回调函数作为参数,并且该回调的参数包括对entities数组和info对象(具有endCursor属性)的显式引用。
对数据存储区API的调用也有限制和配额。以下是详细说明这些内容的官方文档的链接: