我已經編寫了一個存儲過程,用於爲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。 –