Azure CosmosDb存储过程IfMatch谓词

时间:2018-11-17 21:50:26

标签: javascript azure stored-procedures azure-cosmosdb etag

在DocDb存储过程中,作为检索要变异的数据的过程的第一步,我读取并使用了与etag匹配的数据,如下所示:

collection.readDocument(reqSelf, function(err, doc) {
    if (doc._etag == requestEtag) {
        // Success - want to update
    } else {
        // CURRENTLY: Discard the read result I just paid lots of RUs to read 
        // IDEALLY: check whether response `options` or similar indicates retrieval
                    was skipped due to doc not being present with that etag anymore 
        ...
        // ... Continue with an alternate strategy
    }
});

是否有一种方法可以将options传递给readDocument调用,以便通知回调:“它已更改,因此我们未按您的要求获得它”?

(我真正的问题是我找不到the readDocument undocumentation in the js-server docs以外的任何文档)

2 个答案:

答案 0 :(得分:1)

从技术上讲,您可以通过创建一个responseOptions对象并将其传递给调用来实现。

function sample(selfLink, requestEtag) {
    var collection = getContext().getCollection();

    var responseOptions = { accessCondition: { type: "IfMatch", condition: requestEtag } };

    var isAccepted = collection.readDocument(selfLink, responseOptions, function(err, doc, options) {
        if(err){
            throw new Error('Error thrown. Check the status code for PreconditionFailed errors');
        }

        var response = getContext().getResponse();
        response.setBody(doc);

    });

    if (!isAccepted) throw new Error('The query was not accepted by the server.');
}

但是,即使您提供的etag不是文档所拥有的etag,也不会出现错误,并且可以正确地收回文档本身。只是不应该在存储过程中使用readDocument函数。

答案 1 :(得分:0)

感谢@Nick Chapsas的推动,this self-answer from @Redman我认为我可以实现自己的目标(通过自我链接阅读当前文档,或者通过更新该文档的新链接承载相同的id),而是在存储过程中生成一个Alt链接,如下所示:

var docId = collection.getAltLink() + "/docs/"+req.id;
var isAccepted = collection.readDocument(docId, {}, function (err, doc, options) {
    if (err) throw err;
    // Will be null or not depending on whether it exists
    executeUpsert(doc);
});
if (!isAccepted) throw new Error("readDocument not Accepted");