简体   繁体   English

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

[英]Google Cloud Datastore, how to query for more results

Straight and simple, I have the following function, using Google Cloud Datastore Node.js API: 简单明了,我使用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);
    }
  });
}

The Datastore API object is in the variable this.datastore ; 数据存储区API对象位于变量this.datastore

The goal of this function is to fetch all results for a given query, notwithstanding any limits on the number of items returned per single runQuery call. 该功能的目标是获取给定查询的所有结果,尽管每个runQuery调用返回的项数runQuery

I have not yet found out about any definite hard limits imposed by the Datastore API on this, and the documentation seems somewhat opaque on this point, but I only noticed that I always get results[1] = { moreResults: 'MORE_RESULTS_AFTER_LIMIT' } , indicating that there are still more results to be fetched, and the results[1].endCursor remains stuck on constant value that is passed on again on each iteration. 我尚未发现Datastore API对此施加的任何明确的硬性限制,并且文档在这一点上似乎有些模糊,但是我只注意到我总是得到results[1] = { moreResults: 'MORE_RESULTS_AFTER_LIMIT' } ,指示还有更多结果要提取,并且results[1].endCursor仍然停留在恒定值上,该常数在每次迭代时再次传递。

So, given some simple query that I plug into this function, I just go on running the query iteratively, setting the query start cursor (by doing query.start(queryCursor); ) to the endCursor obtained in the result of the previous query. 因此,给定插入此函数的一些简单查询,我将继续迭代运行查询,将查询开始游标(通过执行query.start(queryCursor); )设置为在上一个查询结果中获得的endCursor And my hope is, obviously, to obtain the next bunch of results on each successive query in this iteration. 很显然,我的希望是在此迭代中的每个后续查询上获得下一组结果。 But I always get the same value for results[1].endCursor . 但是我总是得到与results[1].endCursor相同的值。 My question is: Why? 我的问题是: 为什么?

Conceptually, I cannot see a difference to this example given in the Google Documentation : 从概念上讲,我看不出此示例与Google文档中给出的区别:

// 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];
    });
}

(except for the fact, that I don't specify a limit on the size of the query result by myself, which I have also tried, by setting it to 1000, which does not change anything.) (除了我自己没有对查询结果的大小进行限制(我也尝试过)的限制(将其设置为1000,这没有任何改变)。

Why does my code run into this infinite loop, stuck on each step at the same "endCursor"? 为什么我的代码会陷入这个无限循环,而每个循环都停留在同一“ endCursor”上? And how do I correct this? 我该如何纠正呢?

Also, what is the hard limit on the number of results obtained per call of datastore.runQuery() ? 另外,每次调用datastore.runQuery()获得的结果数的硬性限制是多少? I have not found this information in the Google Datastore documentation thus far. 到目前为止,我尚未在Google数据存储区文档中找到此信息。

Thanks. 谢谢。

Looking at the API documentation for the Node.js client library for Datastore there is a section on that page titled "Paginating Records" that may help you. 查看Datastore的Node.js客户端库的API文档 ,该页面上的标题为“分页记录”的部分可能会对您有所帮助。 Here's a direct copy of the code snippet from the section: 这是该部分的代码片段的直接副本:

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

Maybe you can try using one of the other syntax options (instead of Promises). 也许您可以尝试使用其他语法选项之一(而不是Promises)。 The runQuery method can take a callback function as an argument, and that callback's parameters include explicit references to the entities array and the info object (which has the endCursor as a property). runQuery方法可以将回调函数作为参数,并且该回调的参数包括对实体数组和info对象(具有endCursor作为属性)的显式引用。

And there are limits and quotas imposed on calls to the Datastore API as well. 而且,对Datastore API的调用也受到限制和配额。 Here are links to official documentation that address them in detail: 以下是指向官方文档的链接,详细说明了这些链接:

Limits 限度

Quotas 配额

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM