我已经编写了一个存储过程,用于为DocumentDB集合中的所有文档添加一个Type属性。不幸的是,更新一个文档后存储过程失败。该集合包含大约5000个文档。DocumentDB更新多个文档失败
这里是存储过程:
function updateSproc() {
var collection = getContext().getCollection();
var collectionLink = collection.getSelfLink();
var response = getContext().getResponse();
var responseBody = {
updated: 0,
continuation: true,
error: "",
log: ""
};
// Validate input.
tryQueryAndUpdate();
// Recursively queries for a document by id w/ support for continuation tokens.
// Calls tryUpdate(document) as soon as the query returns a document.
function tryQueryAndUpdate(continuation) {
var query = { query: "SELECT * FROM root c WHERE NOT is_defined(c.Type)", parameters: []};
var requestOptions = { continuation: continuation};
var isAccepted = collection.queryDocuments(collectionLink, query, requestOptions, function(err, documents, responseOptions) {
if (err) {
responseBody.error = err;
throw err;
}
if (documents.length > 0) {
// If documents are found, update them.
responseBody.log += "Found documents: " + documents.length;
tryUpdate(documents);
} else if (responseOptions.continuation) {
responseBody.log += "Continue query";
tryQueryAndUpdate(responseOptions.continuation);
} else {
responseBody.log += "No more documents";
responseBody.continuation = false;
response.setBody(responseBody);
}
});
// If we hit execution bounds - throw an exception.
if (!isAccepted) {
responseBody.log += "Query not accepted";
response.setBody(responseBody);
}
}
// Updates the supplied document according to the update object passed in to the sproc.
function tryUpdate(documents)
{
if (documents.length > 0) {
responseBody.log += "Updating documents " + documents.length;
var document = documents[0];
// DocumentDB supports optimistic concurrency control via HTTP ETag.
var requestOptions = { etag: document._etag};
document.Type="Type value";
// Update the document.
var isAccepted = collection.replaceDocument(document._self, document, requestOptions, function(err, updatedDocument, responseOptions) {
if (err) {
responseBody.error = err;
throw err;
}
responseBody.updated++;
documents.shift();
tryUpdate(documents);
});
// If we hit execution bounds - throw an exception.
if (!isAccepted) {
responseBody.log += "Update not accepted";
response.setBody(responseBody);
}
} else {
tryQueryAndUpdate();
}
}}
根据返回的响应,我可以看到该查询返回100个文档。 tryUpdate被调用两次,但不接受第二次调用replaceDocument。为什么当有很多文件需要更新时不被接受?
我花了大约20分钟的时间来看这个,我没有看到任何明显的。我看到的唯一小事不会导致你的问题。即使isAccepted为false,也可以调用tryUpdate(),这意味着您可能会在DocumentDB告诉您它不再接受操作之后尝试调用replaceDocument()。我唯一可以尝试的方法是将文档放在顶层函数作用域中,然后在查询中将您的回调改为“结果”而不是“文档”,并在错误发生后立即添加“文档=结果”检查。 –
哦,它看起来像你的代码将永远不会看到调用tryQueryAndUpdate一个延续块,但这意味着你不能得到第二页,它不会导致你的第二个replaceDocuments()调用失败。我会更多的面条,也许尝试它自己的生活。 –
哦,如果您将文档移动到顶层作用域中,请记住不要将文档传递到tryUpdate。 –