I have a boolean "deleted" column in my database and I'm trying to scan all records that are not deleted (it's a soft delete)
var scanParams = {
TableName: "students",
FilterExpression: "deleted = :deleted",
ExpressionAttributeValues: {
":deleted": false,
},
};
const scan = await db.scan(scanParams).promise();
this does not return any data because I'm not storing my records with deleted = false. I only add deleted = true when the records are deleted.
I tried with
ExpressionAttributeValues: {
":deleted": "",
},
but now I get no records at all. thank you.
Try to reverse your scan condition - Get items that have delete is NOT true.
var scanParams = {
TableName: "students",
FilterExpression: "deleted <> :deleted", // NOT EQUAL TRUE -> empty or false
ExpressionAttributeValues: {
":deleted": true,
},
};
const scan = await db.scan(scanParams).promise();
Related
I have an item in my DynamoDB table that looks like this:
{
"qid": {
"S": "0"
},
"options": {
"L": [
{
"S": "Summer"
},
{
"S": "Winter"
}
]
},
"votes": {
"L": [
{
"N": "11"
},
{
"N": "13"
}
]
}
}
With a lambda function, I want to update one of the elements in the votes list. I want to update the index that matches the index of the option I get from the event (the event has qid, option and number of votes). So here is what I tried:
const AWS = require('aws-sdk');
const docClient = new AWS.DynamoDB.DocumentClient();
exports.handler = async (event, context) => {
const qid = event.qid;
const option = event.option;
const vote = event.vote;
const params = {
TableName : 'QnV',
Key: {
qid: qid
}
}
try {
const data = await docClient.get(params).promise()
const options = data.Item.options;
const index = options.findIndex(option)
const updateParams = {
TableName: 'QnV',
Key: {
'qid': qid
},
UpdateExpression: 'set votes[:index] = :vote',
ExpressionAttributeValues: {
':index': index,
':vote': vote
},
ReturnValues: 'UPDATED_NEW'
};
const updateData = await docClient.update(updateParams).promise();
return {
statusCode: 200,
body: JSON.stringify(updateData)
};
} catch (err) {
return {
statusCode: 500,
body: JSON.stringify(err)
};
}
};
I tried to test it with this:
{
"qid": "0",
"option": "Winter",
"vote": 14
}
But I get an error of 500 and an empty body. It looks like the update params variable is empty, but I don't understand why.
I tried to search online but it looks like I'm doing everything correctly (but if that was the case I didn't have a problem). I also didn't forget to grant permission to the function.
Edit: As suggested, I change the body of the error to err.message, and got this:
{
"statusCode": 500,
"body": "\"Winter is not a function\""
}
Please help me find the bug, I would really appreciate it!
Thank you
After more debugging I found the problems. There were two.
Incorrect index method.
const index = options.findIndex(option)
Changed to:
const index = options.indexOf(option)
The way I tried to find the index in updateParams was incorrect. Instead of:
UpdateExpression: 'set votes[:index] = :vote',
ExpressionAttributeValues: {
':index': index,
':vote': vote
},
It should be:
UpdateExpression: `set votes[${index}] = :vote`,
ExpressionAttributeValues: {
':vote': {N: vote},
},
I have an update expression like below, which appends a link into the end of a links attribute; but I want to set an extra attribute called twitterLink into NULL in the same UpdateExpression after the append operation is done; can you please help on this?
const params = {
TableName: TABLE_ONE,
Key: {
postId: postId
},
UpdateExpression: "set #links = list_append(if_not_exists(#links, :emptyList), :link",
ExpressionAttributeNames: {
'#links': 'links',
},
ExpressionAttributeValues: {
':link': [link],
':emptyList': []
}
};
I'm trying to structure a friendslist using MongoDB.
This is how I currently have it structured:
{
"_id": {
"$oid": "601c570da04b75fabcd2705d"
},
"user_id": 1,
"friendslist": {
3 : true
}
}
How can I create a query that does a put on my Hashmap (The hashmap is "friendslist") and the key is 3 for the friend's id and the true flag is for the status of the pending friend request. (True meaing they are friends and false would be pending friend request)
This is what I currently have:
const upsertFriendId = db.collection('friends')
.updateOne(
{ user_id: userId },
{ $set: { ???? : ????} },
{ upsert: true }
);
I can't figure out the syntax that I need to put in the $set object.
In-order to ensure that you do not override the rest of the keys inside the friendlist, you can do an update like
const mongoFriendKey = `friendlist.${/* FRIEND_ID_VARIABLE_GOES_HERE */}`;
const upsertFriendId = db.collection('friends')
.updateOne(
{
user_id: userId
},
{
$set:
{
[mongoFriendKey] : true
}
},
{ upsert: true }
);
In the above, replace the /* FRIEND_ID_VARIABLE_GOES_HERE */ with the friend id variable. Doing that, the query will look for a friend with that specific Id, and then it will try to set it to true if not found, without overriding the entire friendlist object of yours.
Also, I hope you know what upsert does, if the update won't find the doc, then it will end up inserting one.
Use below codes, I successfully update an item
https://github.com/serverless/examples/blob/master/aws-node-rest-api-with-dynamodb/todos/update.js#L22-L37
const params = {
TableName: process.env.DYNAMODB_TABLE,
Key: {
id: event.pathParameters.id,
},
ExpressionAttributeNames: {
'#todo_text': 'text',
},
ExpressionAttributeValues: {
':text': data.text,
':checked': data.checked,
':updatedAt': timestamp,
},
UpdateExpression: 'SET #todo_text = :text, checked = :checked, updatedAt = :updatedAt',
ReturnValues: 'ALL_NEW',
};
Then I add more attributes:
const params = {
TableName: process.env.DYNAMODB_TABLE,
Key: {
id: event.pathParameters.id,
},
ExpressionAttributeNames: {
'#user_name': 'name',
},
ExpressionAttributeValues: {
':name': data.name,
':email': data.email,
':username': data.username,
':password': data.password,
':checked': data.checked,
':updatedAt': timestamp,
},
UpdateExpression: 'SET #user_name = :name, email = :email, username = :username, password = :password, checked = :checked, updatedAt = :updatedAt',
ReturnValues: 'ALL_NEW',
};
Above codes work fine if I feed all attributes.
$ cat test/user-1.json
{
"name": "Bob",
"email": "bob#example.com",
"username": "bob",
"password": "adfdsfdsf",
"checked": false
}
But if I only want to update part of them, since I needn't update email and password every time, I got error Couldn't fetch the user item.
$ cat test/user-1.json
{
"name": "Bob",
"username": "bob-1",
"checked": false
}
$ curl -X PUT ${url}/${id} --data '#test/user-1.json'
Couldn't fetch the user item.
So how to change the code that I don't have to update all attributes.
The Update API call will not work as the data.email and data.password are undefined.
I would suggest altering the UpdateExpression when you don't need to update those attributes.
I know this is super old, but in case someone else comes across this, I built basically a params factory -- I have a function that returns my params and my ExpressionAttributeValues object and UpdateExpression string only comprise of the variables that pass my validation
i need to update a list on my aws-dynamo database. i have created a table with partition key : email. then iam insert some email id to the table successfully. Now my table like this
email
manaf1#gmail.com
manaf2#gmail.com
manaf3#gmail.com
Then, i tried to update the table with new key "details" and its value is a list. this is my code
var AWS = require("aws-sdk");
var params =
{
TableName: "manaftable1",
Key: { email: "manaf1#gmail.com" },
UpdateExpression: "set #details = list_append (#details, :detailsinput)",
ExpressionAttributeNames: {
"#details": "details"
},
ExpressionAttributeValues: {
":detailsinput":{ "id": "1","mob": "978956" }
}
};
var docClient = new AWS.DynamoDB.DocumentClient();
docClient.update(params, function (err, data) {
if (err)
console.log(JSON.stringify(err, null, 2));
else
console.log(JSON.stringify(data, null, 2));
});
But i got error like this
{
"message": "Invalid UpdateExpression: Incorrect operand type for operator or function; operator or function: list_append, operand type: M",
"code": "ValidationException",
"time": "2016-10-26T11:04:60.756",
"requestId": "SN0NPRHDFHUKBBJHOVI0DFHHRQNSO5AEMVJFFGHF9ASFHUAAJG",
"statusCode": 400,
"retryable": false,
"retryDelay": 0
}
i need response like this after updation
column1 : email
column2 : details
manaf1#gmail.com |
[{"id":"1","mob":"978956"},{"id":"2","mob":"767886"}]
manaf2#gmail.com |
what is the issue related with my code?
As AWS documentation for list_append says:
The new element must be contained in a list, for example to add 2 to a
list, the operand would be [2]
So you need to append an array of objects, not just an object:
var params =
{
TableName: "manaftable1",
Key: { email: "manaf1#gmail.com" },
UpdateExpression: "set #details = list_append (#details, :detailsinput)",
ExpressionAttributeNames: {
"#details": "details"
},
ExpressionAttributeValues: {
":detailsinput": [{ "id": "1","mob": "978956" }]
}
};
If the property does not exist in the object, you can use if_not_exists operand:
var params =
{
TableName: "manaftable1",
Key: { email: "manaf1#gmail.com" },
UpdateExpression: "set if_not_exists(#details, []) set #details = list_append (#details, :detailsinput)",
ExpressionAttributeNames: {
"#details": "details"
},
ExpressionAttributeValues: {
":detailsinput": [{ "id": "1","mob": "978956" }]
}
};
Use list_append() and if_not_exists() together to append to a potentially non-existent list column:
var params = {
TableName: "manaftable1",
Key: { email: "manaf1#gmail.com" },
UpdateExpression: "set #details = list_append(if_not_exists(#details, :empty_list), :detailsinput)",
ExpressionAttributeNames: {
"#details": "details"
},
ExpressionAttributeValues: {
":detailsinput": [{ "id": "1","mob": "978956" }],
":empty_list": []
}
};
When the details attribute is NOT present in the item, the update expression should have just SET without the list_append.
UpdateExpression : "SET #details = :details"
When the details attribute is present in the item and the new update needs to add additional elements in the list, then list_append can be used to add the new element to the list.
UpdateExpression : "set #details = list_append (#details, :details)"