Azure CosmosDb Stored Procedure IfMatch Predicate
up vote
1
down vote
favorite
In a DocDb stored procedure, as the first step in a process retrieving data that I'm mutating, I read and then use the data iff it matches the etag like so:
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
}
});
Is there a way to pass an options
to the readDocument
call such that the callback will be informed "It's changed so we didn't get it, as you requested" ?
(My real problem here is that I can't find any documentation other than the readDocument
undocumentation in the js-server docs)
javascript azure stored-procedures azure-cosmosdb etag
|
show 5 more comments
up vote
1
down vote
favorite
In a DocDb stored procedure, as the first step in a process retrieving data that I'm mutating, I read and then use the data iff it matches the etag like so:
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
}
});
Is there a way to pass an options
to the readDocument
call such that the callback will be informed "It's changed so we didn't get it, as you requested" ?
(My real problem here is that I can't find any documentation other than the readDocument
undocumentation in the js-server docs)
javascript azure stored-procedures azure-cosmosdb etag
Wait a second. I started writing up the answer but then I thought, why would you do that? The document that you get fromreadDocument
is always the latest document (ofc based on your consistency level). Even if you pass an access condition and the condition isn't met, you will still get the latest document.
– Nick Chapsas
Nov 17 at 23:34
You are seeing it the wrong way. What you need to do is to pass the etag on the update call itself, not the read. That's where the access condition will actually be checked and fail if the document's etag doesn't meet the criteria
– Nick Chapsas
Nov 17 at 23:35
@NickChapsas the advantage of not actually getting the document if it has changed is that the RU charges (and latency due to the data traveling) are avoided - you always pay 1 RU if the etag matches. I get the point of the etag to make the update conditional. In my case, if the etag has changed, then the document has been superseded and I hence need to do a different (more expensive) search (and it's in this case I want to avoid getting data I won't use).
– Ruben Bartelink
Nov 18 at 13:44
The problem is that becausereadDocument
is not meant to work with anaccessCondition
, even if you provide one that doesn't match the etag, you will still get the latest version of the document without any errors.
– Nick Chapsas
Nov 18 at 14:16
I too suspect that is the case - however its a bit ironic that I could do the same pre-flight check from the client side with anIf-Match
predicate for 1 RU before I invoke the stored proc
– Ruben Bartelink
Nov 18 at 15:43
|
show 5 more comments
up vote
1
down vote
favorite
up vote
1
down vote
favorite
In a DocDb stored procedure, as the first step in a process retrieving data that I'm mutating, I read and then use the data iff it matches the etag like so:
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
}
});
Is there a way to pass an options
to the readDocument
call such that the callback will be informed "It's changed so we didn't get it, as you requested" ?
(My real problem here is that I can't find any documentation other than the readDocument
undocumentation in the js-server docs)
javascript azure stored-procedures azure-cosmosdb etag
In a DocDb stored procedure, as the first step in a process retrieving data that I'm mutating, I read and then use the data iff it matches the etag like so:
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
}
});
Is there a way to pass an options
to the readDocument
call such that the callback will be informed "It's changed so we didn't get it, as you requested" ?
(My real problem here is that I can't find any documentation other than the readDocument
undocumentation in the js-server docs)
javascript azure stored-procedures azure-cosmosdb etag
javascript azure stored-procedures azure-cosmosdb etag
edited Nov 17 at 21:56
asked Nov 17 at 21:50
Ruben Bartelink
42.7k17139198
42.7k17139198
Wait a second. I started writing up the answer but then I thought, why would you do that? The document that you get fromreadDocument
is always the latest document (ofc based on your consistency level). Even if you pass an access condition and the condition isn't met, you will still get the latest document.
– Nick Chapsas
Nov 17 at 23:34
You are seeing it the wrong way. What you need to do is to pass the etag on the update call itself, not the read. That's where the access condition will actually be checked and fail if the document's etag doesn't meet the criteria
– Nick Chapsas
Nov 17 at 23:35
@NickChapsas the advantage of not actually getting the document if it has changed is that the RU charges (and latency due to the data traveling) are avoided - you always pay 1 RU if the etag matches. I get the point of the etag to make the update conditional. In my case, if the etag has changed, then the document has been superseded and I hence need to do a different (more expensive) search (and it's in this case I want to avoid getting data I won't use).
– Ruben Bartelink
Nov 18 at 13:44
The problem is that becausereadDocument
is not meant to work with anaccessCondition
, even if you provide one that doesn't match the etag, you will still get the latest version of the document without any errors.
– Nick Chapsas
Nov 18 at 14:16
I too suspect that is the case - however its a bit ironic that I could do the same pre-flight check from the client side with anIf-Match
predicate for 1 RU before I invoke the stored proc
– Ruben Bartelink
Nov 18 at 15:43
|
show 5 more comments
Wait a second. I started writing up the answer but then I thought, why would you do that? The document that you get fromreadDocument
is always the latest document (ofc based on your consistency level). Even if you pass an access condition and the condition isn't met, you will still get the latest document.
– Nick Chapsas
Nov 17 at 23:34
You are seeing it the wrong way. What you need to do is to pass the etag on the update call itself, not the read. That's where the access condition will actually be checked and fail if the document's etag doesn't meet the criteria
– Nick Chapsas
Nov 17 at 23:35
@NickChapsas the advantage of not actually getting the document if it has changed is that the RU charges (and latency due to the data traveling) are avoided - you always pay 1 RU if the etag matches. I get the point of the etag to make the update conditional. In my case, if the etag has changed, then the document has been superseded and I hence need to do a different (more expensive) search (and it's in this case I want to avoid getting data I won't use).
– Ruben Bartelink
Nov 18 at 13:44
The problem is that becausereadDocument
is not meant to work with anaccessCondition
, even if you provide one that doesn't match the etag, you will still get the latest version of the document without any errors.
– Nick Chapsas
Nov 18 at 14:16
I too suspect that is the case - however its a bit ironic that I could do the same pre-flight check from the client side with anIf-Match
predicate for 1 RU before I invoke the stored proc
– Ruben Bartelink
Nov 18 at 15:43
Wait a second. I started writing up the answer but then I thought, why would you do that? The document that you get from
readDocument
is always the latest document (ofc based on your consistency level). Even if you pass an access condition and the condition isn't met, you will still get the latest document.– Nick Chapsas
Nov 17 at 23:34
Wait a second. I started writing up the answer but then I thought, why would you do that? The document that you get from
readDocument
is always the latest document (ofc based on your consistency level). Even if you pass an access condition and the condition isn't met, you will still get the latest document.– Nick Chapsas
Nov 17 at 23:34
You are seeing it the wrong way. What you need to do is to pass the etag on the update call itself, not the read. That's where the access condition will actually be checked and fail if the document's etag doesn't meet the criteria
– Nick Chapsas
Nov 17 at 23:35
You are seeing it the wrong way. What you need to do is to pass the etag on the update call itself, not the read. That's where the access condition will actually be checked and fail if the document's etag doesn't meet the criteria
– Nick Chapsas
Nov 17 at 23:35
@NickChapsas the advantage of not actually getting the document if it has changed is that the RU charges (and latency due to the data traveling) are avoided - you always pay 1 RU if the etag matches. I get the point of the etag to make the update conditional. In my case, if the etag has changed, then the document has been superseded and I hence need to do a different (more expensive) search (and it's in this case I want to avoid getting data I won't use).
– Ruben Bartelink
Nov 18 at 13:44
@NickChapsas the advantage of not actually getting the document if it has changed is that the RU charges (and latency due to the data traveling) are avoided - you always pay 1 RU if the etag matches. I get the point of the etag to make the update conditional. In my case, if the etag has changed, then the document has been superseded and I hence need to do a different (more expensive) search (and it's in this case I want to avoid getting data I won't use).
– Ruben Bartelink
Nov 18 at 13:44
The problem is that because
readDocument
is not meant to work with an accessCondition
, even if you provide one that doesn't match the etag, you will still get the latest version of the document without any errors.– Nick Chapsas
Nov 18 at 14:16
The problem is that because
readDocument
is not meant to work with an accessCondition
, even if you provide one that doesn't match the etag, you will still get the latest version of the document without any errors.– Nick Chapsas
Nov 18 at 14:16
I too suspect that is the case - however its a bit ironic that I could do the same pre-flight check from the client side with an
If-Match
predicate for 1 RU before I invoke the stored proc– Ruben Bartelink
Nov 18 at 15:43
I too suspect that is the case - however its a bit ironic that I could do the same pre-flight check from the client side with an
If-Match
predicate for 1 RU before I invoke the stored proc– Ruben Bartelink
Nov 18 at 15:43
|
show 5 more comments
2 Answers
2
active
oldest
votes
up vote
1
down vote
accepted
Technically you can do that by creating a responseOptions
object and passing it to the call.
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.');
}
However, even if the etag you provide is not the one that the document has, you won't get an error and you will properly get the document itself back. It's just not supposed to work with that using the readDocument
function in a stored procedure.
add a comment |
up vote
0
down vote
Thanks to some pushing from @Nick Chapsas, and this self-answer from @Redman I worked out that in my case I can achieve my goal (either read the current document via the self-link, or the newer one that has replaced it bearing the same id
) by instead generating an Alt link within the stored procedure like so:
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");
add a comment |
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
1
down vote
accepted
Technically you can do that by creating a responseOptions
object and passing it to the call.
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.');
}
However, even if the etag you provide is not the one that the document has, you won't get an error and you will properly get the document itself back. It's just not supposed to work with that using the readDocument
function in a stored procedure.
add a comment |
up vote
1
down vote
accepted
Technically you can do that by creating a responseOptions
object and passing it to the call.
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.');
}
However, even if the etag you provide is not the one that the document has, you won't get an error and you will properly get the document itself back. It's just not supposed to work with that using the readDocument
function in a stored procedure.
add a comment |
up vote
1
down vote
accepted
up vote
1
down vote
accepted
Technically you can do that by creating a responseOptions
object and passing it to the call.
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.');
}
However, even if the etag you provide is not the one that the document has, you won't get an error and you will properly get the document itself back. It's just not supposed to work with that using the readDocument
function in a stored procedure.
Technically you can do that by creating a responseOptions
object and passing it to the call.
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.');
}
However, even if the etag you provide is not the one that the document has, you won't get an error and you will properly get the document itself back. It's just not supposed to work with that using the readDocument
function in a stored procedure.
answered Nov 18 at 22:29
Nick Chapsas
2,184214
2,184214
add a comment |
add a comment |
up vote
0
down vote
Thanks to some pushing from @Nick Chapsas, and this self-answer from @Redman I worked out that in my case I can achieve my goal (either read the current document via the self-link, or the newer one that has replaced it bearing the same id
) by instead generating an Alt link within the stored procedure like so:
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");
add a comment |
up vote
0
down vote
Thanks to some pushing from @Nick Chapsas, and this self-answer from @Redman I worked out that in my case I can achieve my goal (either read the current document via the self-link, or the newer one that has replaced it bearing the same id
) by instead generating an Alt link within the stored procedure like so:
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");
add a comment |
up vote
0
down vote
up vote
0
down vote
Thanks to some pushing from @Nick Chapsas, and this self-answer from @Redman I worked out that in my case I can achieve my goal (either read the current document via the self-link, or the newer one that has replaced it bearing the same id
) by instead generating an Alt link within the stored procedure like so:
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");
Thanks to some pushing from @Nick Chapsas, and this self-answer from @Redman I worked out that in my case I can achieve my goal (either read the current document via the self-link, or the newer one that has replaced it bearing the same id
) by instead generating an Alt link within the stored procedure like so:
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");
answered Nov 18 at 22:20
Ruben Bartelink
42.7k17139198
42.7k17139198
add a comment |
add a comment |
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53355886%2fazure-cosmosdb-stored-procedure-ifmatch-predicate%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Wait a second. I started writing up the answer but then I thought, why would you do that? The document that you get from
readDocument
is always the latest document (ofc based on your consistency level). Even if you pass an access condition and the condition isn't met, you will still get the latest document.– Nick Chapsas
Nov 17 at 23:34
You are seeing it the wrong way. What you need to do is to pass the etag on the update call itself, not the read. That's where the access condition will actually be checked and fail if the document's etag doesn't meet the criteria
– Nick Chapsas
Nov 17 at 23:35
@NickChapsas the advantage of not actually getting the document if it has changed is that the RU charges (and latency due to the data traveling) are avoided - you always pay 1 RU if the etag matches. I get the point of the etag to make the update conditional. In my case, if the etag has changed, then the document has been superseded and I hence need to do a different (more expensive) search (and it's in this case I want to avoid getting data I won't use).
– Ruben Bartelink
Nov 18 at 13:44
The problem is that because
readDocument
is not meant to work with anaccessCondition
, even if you provide one that doesn't match the etag, you will still get the latest version of the document without any errors.– Nick Chapsas
Nov 18 at 14:16
I too suspect that is the case - however its a bit ironic that I could do the same pre-flight check from the client side with an
If-Match
predicate for 1 RU before I invoke the stored proc– Ruben Bartelink
Nov 18 at 15:43