DynamoDB UpdateItem calculation with numbers? - amazon-web-services

I would like my UpdateItem function to add the new value to the previous one but I can't figure out how to use numbers for the calculation and access the current value to be added to the new one.
Here is my working function, what I want to do is included in comment. How can I do it?
{
"TableName": "Votes",
"Key": {
"votesId": {
"S": "$input.path('$.votesId')"
}
},
"UpdateExpression": "set buy = :val1",
"ExpressionAttributeValues" : {
":val1": {
"N": "$input.path('$.buy')"
//Would like: "N": "buy + $input.path('$.buy')"
}
},
"ReturnValues": "ALL_NEW"
}
Here is how I test it:
{
"votesId":1,
"down":0,
"up":0,
"hold":0,
"buy":0,
"sell":0
}

You can use UpdateExpression to indicate which attributes are to be updated and what actions to perform.
Specifically in your case, UpdateExpression supports the following:
SET myNum = myNum + :val

Related

Dynamodb update multiple items in one transaction

In my dynamodb table, I have a scenario where when I add a new item to my table, I need to also increment a counter for another entry in my table.
For instance, when USER#1 follows USER#2, I would like to increment followers count for USER#2.
HashKey
RangeKey
counter
USER1
USER2
USER3
USER2
USER2
USER2
2
I do not want to use auto-increment as I want to control how the increment happens.
Naturally, everything works as expected if I make two update calls to dynamodb. One to create the relationship between users and another to update the count for the other user.
The question is, if it is a good approach to make two such calls or would a transactWrite be a better alternative.
If so how could I make an increment using transactwrite api.
I can add items using the following approach. But I am not sure how I can increment
"TransactItems": [
{
"Put": {
"TableName": "Table",
"Item": {
"hashKey": {"S":"USER1"},
"rangeKey": {"S":"USER2"}
}
}
},
{
"Update": {
"TableName": "TABLE",
"Key": {
"hashKey": {"S":"USER2"},
"rangeKey": {"S":"USER2"}
},
"ConditionExpression": "#cefe0 = :cefe0",
"ExpressionAttributeNames": {"#cefe0":"counter"},
"ExpressionAttributeValues": ?? how do I increment here
}
}
]
Transactions would defintely be the best way to approach it, you can increment using SET in the UpdateExpression:
"TransactItems": [
{
"Put": {
"TableName": "Table",
"Item": {
"hashKey": {"S":"USER1"},
"rangeKey": {"S":"USER2"}
}
}
},
{
"Update": {
"TableName": "TABLE",
"Key": {
"hashKey": {"S":"USER2"},
"rangeKey": {"S":"USER2"}
},
"UpdateExpression": "SET #cefe0 = #cefe0 + :cefe0",
"ExpressionAttributeNames": {"#cefe0":"counter"},
"ExpressionAttributeValues": {"cefe0": {"N": "1"}}
}
}
]

Azure Cosmos query to convert into List

This is my JSON data, which is stored into cosmos db
{
"id": "e064a694-8e1e-4660-a3ef-6b894e9414f7",
"Name": "Name",
"keyData": {
"Keys": [
"Government",
"Training",
"support"
]
}
}
Now I want to write a query to eliminate the keyData and get only the Keys (like below)
{
"userid": "e064a694-8e1e-4660-a3ef-6b894e9414f7",
"Name": "Name",
"Keys" :[
"Government",
"Training",
"support"
]
}
So far I tried the query like
SELECT c.id,k.Keys FROM c
JOIN k in c.keyPhraseBatchResult
Which is not working.
Update 1:
After trying with the Sajeetharan now I can able to get the result, but the issue it producing another JSON inside the Array.
Like
{
"id": "ee885fdc-9951-40e2-b1e7-8564003cd554",
"keys": [
{
"serving": "Government"
},
{
"serving": "Training"
},
{
"serving": "support"
}
]
}
Is there is any way that extracts only the Array without having key value pari again?
{
"userid": "e064a694-8e1e-4660-a3ef-6b894e9414f7",
"Name": "Name",
"Keys" :[
"Government",
"Training",
"support"
]
}
You could try this one,
SELECT C.id, ARRAY(SELECT VALUE serving FROM serving IN C.keyData.Keys) AS Keys FROM C
Please use cosmos db stored procedure to implement your desired format based on the #Sajeetharan's sql.
function sample() {
var collection = getContext().getCollection();
var isAccepted = collection.queryDocuments(
collection.getSelfLink(),
'SELECT C.id,ARRAY(SELECT serving FROM serving IN C.keyData.Keys) AS keys FROM C',
function (err, feed, options) {
if (err) throw err;
if (!feed || !feed.length) {
var response = getContext().getResponse();
response.setBody('no docs found');
}
else {
var response = getContext().getResponse();
var map = {};
for(var i=0;i<feed.length;i++){
var keyArray = feed[i].keys;
var array = [];
for(var j=0;j<keyArray.length;j++){
array.push(keyArray[j].serving)
}
feed[i].keys = array;
}
response.setBody(feed);
}
});
if (!isAccepted) throw new Error('The query was not accepted by the server.');
}
Output:

DynamoDB DeleteItem Expressions not working

I'm getting a really weird error when I try to preform a DeleteItem with expressions. Can anyone help?
Thanks
{
"TableName": "MyTable",
"Key": {
"SESSION": {
"S": "1E3E181C-1238-D168-725D-9B0FE7F5EA3E"
}
},
"FilterExpression": "#X < :X ",
"ExpressionAttributeNames": {
"#X": "ttl"
},
"ExpressionAttributeValues": {
":X": {
"N": "1502905189"
}
}
}
// RESULT
Array
(
[__type] => com.amazon.coral.validate#ValidationException
[message] => ExpressionAttributeNames can only be specified when using expressions
)
The delete item should not contain FilterExpression. If you would like to delete the item based on some condition, you can use ConditionExpression to specify the condition.
"ConditionExpression" : "#X < :X "
Please replace the FilterExpression with ConditionExpression.

mapreduce in couchDB and getting the MAX result after mapreduce

I am a beginner to couchDB.
I have data as below:
one:[{
"name":abc,
"value":1
},
{
"name":efg,
"value":1
},
{
"name":abc,
"value":1
},
I would like to get the count of similar keys and get the maximum.
e.g. in my case "abc" is twice. so the maximum(reduce function) should return
result: {"name":abc,value:2}
Did you try this design document:
{
"_id":"_design/company",
"views":
{
"abc_customers": {
"map": "function(doc) { if (doc.name == 'abc') emit(doc.name,doc.value) }",
"reduce" : "_count"
},
"efg_customers": {
"map": "function(doc) { if (doc.name == 'efg') emit(doc.name,doc.value) }",
"reduce" : "_count"
}
}
}
See this one for a comparison of _count and _sum. Possibly you need _count.
By the above CouchDB design document, you will get count for each doc.name of abc, efg, ... and then you can do a search for max/min of counts.

How to concatenate method request parameters in body mapping template AWS API Gateway

I am trying to retrieve a list of entries from AWS DynamoDB with a primary hash and sort key composite.
The idea is to retrieve a list which matches a given query string value which is a part of the sort key, for example, the sort keys can be a_b_c, a_d_e, a_f_g and i need to get the all entries with b in it.
I am asking for three query strings from the client and concatenating them in the body mapping template in the integration request section of AWS API gateway.
I am searching the web to accomplish the same but haven't been successful in finding a solution.
It would save a lot of time if somebody could help me with this.
Below is my approach.
{
"TableName": "$util.escapeJavaScript("$context.stage\_TableName").replaceAll("\\","")",
"FilterExpression": "identityId = :v1 and aWithbWithc = :v2 + _ + :v3 + _ + :v4",
"ExpressionAttributeValues": {
":v1": {
"S": "$context.identity.cognitoIdentityId"
},
":v2" : {
"S" : "$input.params('a')"
},
":v3" : {
"S" : "$input.params('b')"
},
":v4" : {
"S" : "$input.params('c')"
}
}
}
I have found the solution and putting it out here.
{
"TableName": "$util.escapeJavaScript("$context.stage\_TableName").replaceAll("\\","")",
"FilterExpression": "identityId = :v1 and aWithbWithc = :v2",
"ExpressionAttributeValues": {
":v1": {
"S": "$context.identity.cognitoIdentityId"
},
":v2" : {
"S" : "$util.escapeJavaScript($input.params('a'))__$util.escapeJavaScript($input.params('b'))__$util.escapeJavaScript($input.params('c'))"
}
}
}
you can have something like
{
#set($tableNameSuffix = "_TableName")
"TableName": "$stageVariables.environment$tableNameSuffix",
"ConsistentRead": true,
"KeyConditionExpression": "XXX = :val",
"ExpressionAttributeValues": {
":val": {
"S": "$method.request.path.xxx"
}
}
}