文档DB 5秒存储过程执行限制

时间:2015-08-12 19:43:30

标签: azure-cosmosdb

我有一个存储过程,返回4000个文档,由于5秒执行限制,我的sproc没有重新调整任何数据。我试图处理集合接受的值,但它没有按预期工作。

我试图将响应设置为" return"在5秒限制命中的情况下,sproc没有设置响应。

function getRequirementNodes() 
{
var context = getContext();
var response = context.getResponse();
var collection = context.getCollection();
var collectionLink = collection.getSelfLink();
var nodesBatch = [];
var continueToken= true;

var query = { query: 'SELECT * from root '};

getNodes(null)

function getNodes(continuation)
{
   var requestOptions = {continuation: continuation};
   var accepted = collection.queryDocuments(collectionLink, query,    requestOptions,
   function(err, documentsRead, responseOptions) 
   {
    if (documentsRead.length > 0)
    {
        nodesBatch = nodesBatch.concat(documentsRead);
    }
    else if (responseOptions.continuation)
    {
       continueToken = responseOptions.continuation
       nodesBatch = nodesBatch.concat(documentsRead);
       getNodes(responseOptions.continuation);
    }
        else 
        {
            continueToken= false;
            response.setBody(nodesBatch);
        }
        });

    if (!accepted) 
    { 
       response.setBody("return");
    } 
}
}

1 个答案:

答案 0 :(得分:6)

脚本返回一个空响应,因为从不调用包含response.setBody()的块。

我会解释。让我们打破queryDocuments回调的这一部分:

if (documentsRead.length > 0) {
    nodesBatch = nodesBatch.concat(documentsRead);
} else if (responseOptions.continuation) {
    continueToken = responseOptions.continuation
    nodesBatch = nodesBatch.concat(documentsRead);
    getNodes(responseOptions.continuation);
} else {
    continueToken = false;
    response.setBody(nodesBatch);
}

请注意,如果查询在第一页内有结果(最有可能)...脚本会将查询结果附加到nodesBatch

if (documentsRead.length > 0) {
    nodesBatch = nodesBatch.concat(documentsRead);
}

然后脚本将完成。响应正文未设置(空),如果存在延续令牌,脚本不会发出后续查询。

假设集合不为空,那么这可能就是您遇到的行为。

注意:如果您要查询大型数据集,则可以达到响应大小限制(1 MB)。

我已经重新编写了脚本来修复上面的问题,并且已经包含一个片段来说明如何处理响应大小限制:

function getRequirementNodes(continuationToken) {
  var context = getContext();
  var response = context.getResponse();
  var collection = context.getCollection();
  var collectionLink = collection.getSelfLink();
  var nodesBatch = [];
  var lastContinuationToken;
  var responseSize = 0;

  var query = {
    query: 'SELECT * FROM root'
  };

  getNodes(continuationToken);

  function getNodes(continuationToken) {
    // Tune the pageSize to fit your dataset.
    var requestOptions = {
      continuation: continuationToken,
      pageSize: 1
    };

    var accepted = collection.queryDocuments(collectionLink, query, requestOptions,
      function(err, documentsRead, responseOptions) {
        // The size of the current query response page.
        var queryPageSize = JSON.stringify(documentsRead).length;

        // DocumentDB has a response size limit of 1 MB.
        if (responseSize + queryPageSize < 1024 * 1024) {
          // Append query results to nodesBatch.
          nodesBatch = nodesBatch.concat(documentsRead);

          // Keep track of the response size.
          responseSize += queryPageSize;

          if (responseOptions.continuation) {
            // If there is a continuation token... Run the query again to get the next page of results
            lastContinuationToken = responseOptions.continuation;
            getNodes(responseOptions.continuation);
          } else {
            // If there is no continutation token, we are done. Return the response.
            response.setBody({
              "message": "Query completed succesfully.",
              "queryResponse": nodesBatch
            });
          }
        } else {
          // If the response size limit reached; run the script again with the lastContinuationToken as a script parameter.
          response.setBody({
            "message": "Response size limit reached.",
            "lastContinuationToken": lastContinuationToken,
            "queryResponse": nodesBatch
          });
        }
      });

    if (!accepted) {
      // If the execution limit reached; run the script again with the lastContinuationToken as a script parameter.
      response.setBody({
        "message": "Execution limit reached.",
        "lastContinuationToken": lastContinuationToken,
        "queryResponse": nodesBatch
      });
    }
  }
}