node.js - Google Cloud Datastore,如何查询更多结果

标签 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);
    }
  });
}

Datastore API 对象位于变量 this.datastore 中;

此函数的目标是获取给定查询的所有结果,尽管每个 runQuery 调用返回的项目数量有任何限制。

我还没有发现 Datastore API 对此施加的任何明确的硬性限制,并且文档在这一点上似乎有些不透明,但我只注意到我总是 结果[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 数据存储文档中找到此信息。

谢谢。

最佳答案

查看API documentation对于数据存储的 Node.js 客户端库,该页面上有一个标题为“分页记录”的部分可能会对您有所帮助。以下是该部分中代码片段的直接副本:

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方法可以将回调函数作为参数,并且该回调的参数包括对实体数组和信息对象(其具有 endCursor 作为属性)的显式引用。

对数据存储 API 的调用也有限制和配额。以下是详细解决这些问题的官方文档的链接:

Limits

Quotas

关于node.js - Google Cloud Datastore,如何查询更多结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44184469/

相关文章:

python - 查找错误 : No installed app with label 'mobile_backend/'

python - DateTimeProperty 在 Google App Engine 中设置为日期时间时出错

node.js - 使用 Express 显示图像,而不是下载它

javascript - Hapi/Joi 验证 - 不同的 Joi.regex 取决于另一个键值

python - 如何过滤字典以匹配我的 ndb.Model 子类的属性

go - 无法从使用 IncompleteKey() 创建的数据存储中检索实体

python - 如何从数据存储区刷新 NDB 实体?

javascript - 如何在 Node.js 中注册 url 协议(protocol)处理程序

javascript - 在 NodeJS 中设置路径

node.js - 如何使用事务循环不同的 Sequelize 查询