Я написал хранимую процедуру af для добавления свойства Type ко всем документам в коллекции DocumentDB. К сожалению, хранимая процедура завершилась неудачей после обновления только одного документа. Коллекция содержит около 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 минут на это, и я не вижу ничего очевидного. Единственная незначительная вещь, которую я видел, не вызовет вашей проблемы. Вы вызываете tryUpdate(), даже если isAccepted является false, что означает, что вы можете попытаться вызвать replaceDocument() после того, как DocumentDB сообщит вам, что он больше не принимает операции. Единственное, что я мог попробовать, это поместить документы в область функций верхнего уровня, а затем изменить обратный вызов в запросе, чтобы сказать «результаты» вместо «документы» и добавить «документы = результаты» сразу после вашей ошибки проверить. –
Ой, похоже, ваш код никогда не увидит блок, который вызывает tryQueryAndUpdate с продолжением, но это будет означать, что вы не можете получить вторую страницу, это не приведет к сбою второго вызова replaceDocuments().Я буду лапшу на нем еще и, возможно, попробую жить сам. –
Ох, если вы переместите документы в область верхнего уровня, тогда не забудьте не передавать документы в файл tryUpdate. –