我有一个非常简单的存储过程,它向许多文档返回 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#),然后再次调用传递 token 的存储过程。我还没有找到代码示例。这也是确保全额返回的唯一方法吗?这只是一个存储过程问题吗?我是否最好只使用 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");
}
}
}
最佳答案
if there are many documents to be returned ie 20000 not all documents are returned. I think i am running into the issue where i need to pass a continuationToken.
当查询数据相当庞大时,当然需要考虑在存储过程中使用延续 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");
}
}
}
I have read other posts that states that we will need to return to client(c#) then make another call to the sproc passing in a token. I havent been able to find a code sample.
据我所知,存储过程有5
秒的运行限制( Is it possible to disable the 5 second time limit for Azure CosmosDB stored procedures ,如果您的存储过程超时,则需要调用[ExecuteStoredProcedureAsync][1]
在您的客户端并将继续 token 作为参数传递。
Will i be better off to just use client.CreateDocumentQuery that will simply return all records in one call?
据我所知,存储过程是在服务器端运行的JS代码脚本。我认为性能比使用客户端调用SDK更有效。但受限于JS语法和运行时间。如果您不能容忍这些功能,我建议您可以通过客户端SDK来完成您的需求。
希望对您有帮助。如有任何疑问,请告诉我。
关于azure - CosmosDB 存储过程不返回所有文档,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51601158/