Currently, I'm checking if the item exists with a query and then I'm using put or updateItem, I want to change it and make a single call to DDB. I want to make a query that will update or create item.
Here is a example of my item:
{
id: 'dsfadsf'
fa: { "apple" : { "S" : "76-100" }, "yolo" : { "S" : "0-25" }
pa: { "finish" : { "BOOL" : false }, "userKey" : { "S" : "3e299e12-9e66" } }
createdAt: 32432432423
}
item types:
createdAt - Number
fa - Map
pa - Map
id - String
finish - Boolean
key - String
If item exists I want to push a new item like {papa: 'dsfadsf'} (never modify existing item inside fa Map) and modify finish value inside pa Map
This is the item after the update:
{
id: 'dsfadsf'
fa: { "apple" : { "S" : "76-100" }, "yolo" : { "S" : "0-25" }, "papa": { "S" : "dsfadsf"} }
pa: { "finish" : { "BOOL" : true }, "userKey" : { "S" : "3e299e12-9e66" } }
createdAt: 32432432423
}
Here is what I tried and its not working
{
TableName: tableName,
Key: {
id: "dsfadsf",
},
UpdateExpression: `SET #id = :id, fa.${itemName} = if_not_exists(fa.${itemName}, :text), pa.finish = if_not_exists(pa.finish, :finishval), #ca = :ca`,
ExpressionAttributeNames: {
"#id": "id",
"#ca": createdAt
},
ExpressionAttributeValues: {
":id": "7fd9a81b-7a7c-4cfb-9c84-25dc2798a8f7",
":text": itemText,
":finishval": true,
":ca": 32432432423
},
ConditionExpression: `attribute_not_exists(id)`,
};
The main difference between the two is, PutItem will Replace an entire item while UpdateItem will Update it. Eg. This will replace Name and Gender and now new Item is UserId and Country. While if you want to update an item from Name = ABC to Name = 123 you have to use UpdateItem .
To update an existing item in an Amazon DynamoDB table, you use the UpdateItem operation. You must provide the key of the item that you want to update. You must also provide an update expression, indicating the attributes that you want to modify and the values that you want to assign to them.
Edits an existing item's attributes, or adds a new item to the table if it does not already exist.
TLDR
This isn't possible with the current structure of your item. Change fa
& pa
to be string sets, get rid of finish: true
& use the ADD update expression.
This is not possible with the current structure of your item. Here's why — To meet your requirement, UpdateExpression
needs to be of the form:
if "fa" exists, add {"papa":"dsfadsf"} to it
else, create new "fa"={"papa":"dsfadsf"}
Of all the DynamoDB update expressions, only SET & ADD can be used in this scenario.
The above if else
condition cannot be expressed in an UpdateExpression
with SET due to the following reasons:
SET fa.papa = 'dsfadsf'
will update fa
if it exists, but if it doesn't, you get the error The document path provided in the update expression is invalid for update
.
SET fa = {"papa":"dsfadsf"}
will create new fa
but overwrite it if it exists.
If you try to combine ADD & SET to achieve the above if else
condition, into something like ADD fa {} SET fa.papa = dsfadsf
, you get the error Two document paths overlap with each other; must remove or rewrite one of these paths
So we're only left with the ADD expression now, but ADD only works on sets. So if you can afford to turn the contents of fa
& pa
into sets of strings, you can achieve your goal of "create or update in 1 go". Here's how it'll work:
The original item structure has to be:
{
"ca": 32432432423,
"fa": [
"apple:76-100",
"yolo:0-25"
],
"id": "dsfadsf",
"pa": [
"key:9e66"
]
}
In DynamoDB JSON, that's:
{
"ca": {
"N": "32432432423"
},
"fa": {
"SS": [
"apple:76-100",
"yolo:0-25"
]
},
"id": {
"S": "dsfadsf"
},
"pa": {
"SS": [
"key:9e66"
]
}
}
Now, using the following code:
let AWS = require("aws-sdk")
let docClient = new AWS.DynamoDB.DocumentClient()
docClient.update({
TableName: "my-table",
Key: { id: "dsfadsf" },
UpdateExpression: `ADD fa :fa, pa :pa SET ca = :ca`,
ExpressionAttributeValues: {
":fa": docClient.createSet(["papa:dsfadsf"]),
":pa": docClient.createSet(["finished"]),
":ca": 32432432423
}
}
If an item with the id
"dsfadsf" already exists, it's updated as follows:
{
"ca": {
"N": "32432432423"
},
"fa": {
"SS": [
"apple:76-100",
"papa:dsfadsf",
"yolo:0-25"
]
},
"id": {
"S": "dsfadsf"
},
"pa": {
"SS": [
"finished",
"key:9e66"
]
}
}
If an item with the id
"dsfadsf" does NOT exist, it's created as follows:
{
"ca": {
"N": "32432432423"
},
"fa": {
"SS": [
"papa:dsfadsf"
]
},
"id": {
"S": "dsfadsf"
},
"pa": {
"SS": [
"finished"
]
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With