首页 文章

CosmosDB存储过程不返回所有文档

提问于
浏览
0

我有一个非常简单的存储过程,返回0到很多文档 . 这是代码:

function GetAllDocuments(numberOfDays){

  var context = getContext();
  var response = context.getResponse();
  var collection = context.getCollection();
  var collectionLink = collection.getSelfLink();

  var today  = new Date();  
  today.setDate(today.getDate() - numberOfDays);
  var inSeconds = today.getTime() / 1000; 
  var filterQuery = 'SELECT * FROM c WHERE c._ts >' + inSeconds;

  console.log(filterQuery);
  collection.queryDocuments(collectionLink, filterQuery, {pageSize:-1},
    function(err, documents) {
      response.setBody(response.getBody() + JSON.stringify(documents));
    }
  );
}

我面临的问题是,如果有很多文件需要退回,即20000并非所有文件都被退回 . 我想我遇到了需要传递continuationToken的问题 . 我已阅读其他帖子,声明我们需要返回客户端(c#),然后再次调用sproc传递令牌 . 我还没能找到代码示例 . 也是确保全额退货的唯一方法吗?它只是一个存储过程问题吗?我会更好地使用client.CreateDocumentQuery,它只会在一次调用中返回所有记录吗?

感谢您的任何反馈!

这是使用Jay的样本的新代码:

function GetAllDocumentsNew(numberOfDays) {

       var collection = getContext().getCollection();
       var collectionLink = collection.getSelfLink();
       var response = getContext().getResponse();
       var docCount = 0;
       var counter = 0;
       var returnArray = [];

       var today  = new Date();  
       today.setDate(today.getDate() - numberOfDays);
       var inSeconds = today.getTime() / 1000; 
       //var filterQuery = 'SELECT * FROM c WHERE c._ts >' + inSeconds;
       var filterQuery = "select * from c where c._ts > 1531763849.225 and c._ts <1532637743.261 and c.ProcessTypeID = 1";

       console.log(filterQuery);

       tryQuery();

       function tryQuery(continuation) {
            var query = {
                query: filterQuery
            };

            var requestOptions = {
                MaxItemCount: 10000,
                continuation: continuation
            };

            var isAccepted =
                collection
                .queryDocuments(collectionLink,
                                query,
                                requestOptions,
                                function queryCallback(err, documents,responseOptions) {
                                         if (err) throw err;
                                         if (documents.length > 0) {

                                            docCount = documents.length;
                                            console.log(docCount.toString());
                                            for (var i=0; i<docCount; i++){
                                                returnArray.push(documents[i]);
                                            }

                                           getContext().getResponse().setBody(returnArray);
                                          }
                                          else if (responseOptions.continuation) {
                                              // Else if the query came back empty, but with a continuation token; 
                                              // repeat the query with the token.
                                            tryQuery(responseOptions.continuation);
                                          } else {
                                                 throw new Error("Document not found.");
                                                 }
                                });

            if (!isAccepted) {
                throw new Error("The stored procedure timed out");
            }
        }
    }

1 回答

  • 0

    如果有很多文件需要退回,即20000并非所有文件都被退回 . 我想我遇到了需要传递continuationToken的问题 .

    当查询数据非常庞大时,您需要考虑在存储过程中使用continuation token . 你可以参考下面的伪代码:

    function GetAllDocuments(numberOfDays) {
    
           var collection = getContext().getCollection();
           var collectionLink = collection.getSelfLink();
           var response = getContext().getResponse();
           var docCount = 0;
           var counter = 0;
           var returnArray = [];
    
           var today  = new Date();  
           today.setDate(today.getDate() - numberOfDays);
           var inSeconds = today.getTime() / 1000; 
           var filterQuery = 'SELECT * FROM c WHERE c._ts >' + inSeconds;
    
           tryQuery();
    
           function tryQuery(continuation) {
                var query = {
                    query: "select * from root r"
                };
    
                var requestOptions = {
                    MaxItemCount: 1000
                    continuation: continuation
                };
    
                var isAccepted =
                    collection
                    .queryDocuments(collectionLink,
                                    query,
                                    requestOptions,
                                    function queryCallback(err, documents,responseOptions) {
                                             if (err) throw err;
                                             if (documents.length > 0) {
    
                                                docCount = documents.length;
                                                for (var i=0; i<docCount; i++){
                                                    returnArray.push(documents[i]);
                                                }
    
                                               getContext().getResponse().setBody(returnArray);
                                              }
                                              else if (responseOptions.continuation) {
                                                  // Else if the query came back empty, but with a continuation token; 
                                                  // repeat the query with the token.
                                                tryQuery(responseOptions.continuation);
                                              } else {
                                                     throw new Error("Document not found.");
                                                     }
                                    });
    
                if (!isAccepted) {
                    throw new Error("The stored procedure timed out");
                }
            }
        }
    

    我已阅读其他帖子,声明我们需要返回客户端(c#),然后再次调用传递令牌的sproc . 我还没能找到代码示例 .

    据我所知,存储过程有 5 秒运行限制(Is it possible to disable the 5 second time limit for Azure CosmosDB stored procedures.So),如果存储过程超时,则需要在客户端调用 [ExecuteStoredProcedureAsync][1] 并将连续标记作为参数传递 .

    我会更好地使用client.CreateDocumentQuery,它只会在一次调用中返回所有记录吗?

    据我所知,存储过程是在服务器端运行的JS代码脚本 . 我认为性能比使用客户端调用SDK更有效 . 但是,它仅限于JS语法和运行时间 . 如果您无法容忍这些功能,我建议您通过客户端SDK完成您的要求 .

    希望它可以帮助你 . 任何关注,请让我知道 .

相关问题