Google Cloud Datastore,如何查询更多结果

时间:2017-05-25 15:37:56

标签: node.js google-cloud-datastore

直接且简单,我使用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文档中找到此信息。

感谢。

1 个答案:

答案 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的调用也有限制和配额。以下是详细说明这些内容的官方文档的链接:

Limits

Quotas