how to update item in dynamoDB using nodejs? - javascript

how do i update item in dynamoDB using nodejs ?
here is the ITEM list from DynamoDB javascript shell -
"Items": [
{
"EmailId": "swa#acc.com",
"flag": 1,
"deviceOS": "IOS",
"companyName": "VCC",
"snsEndpoint": "00d0sadas",
"CreatedAt": 22112015,
"Otp": "ABCDEF",
},
i want to update flag value to 2 ... this is my code . what do i do?? what am i doing wrong ?? help is appreciated...
var params = {
TableName: 'users',
Key: {
id: {
'S': req.query.id
},
flag: {
'N': 2
}
},
UpdateExpression: 'SET #flag =:val1',
ExpressionAttributeNames: {
'#flag': 'flag' //COLUMN NAME
},
ExpressionAttributeValues: {
':val1': {
'N': 2
},
}
};
dynamodb.updateItem(params, function(err, data) {
if (err) {
console.log('Error :' + err);
} else {
//subscribe(bodydata.id);
console.log('EndpointArn Saved successful');
console.log('Data :' + JSON.stringify(data.flag));
}
});

You are trying to modify the flag: { 'N': 2 } which doesnot exist. But you wanted to modify the flag: { 'N': 1 } value to 2. So try doing like this:
var params = {
TableName: 'users',
Key: {
id: {
'S': req.query.id
},
flag: {
'N': 1
}
},
UpdateExpression: 'SET #flag =:val1',
ExpressionAttributeNames: {
'#flag': 'flag' //COLUMN NAME
},
ExpressionAttributeValues: {
':val1': {
'N': 2
},
}
};
dynamodb.updateItem(params, function(err, data) {
if (err) {
console.log('Error :' + err);
} else {
//subscribe(bodydata.id);
console.log('EndpointArn Saved successful');
console.log('Data :' + JSON.stringify(data.flag));
}
});

Related

How to use group by and sum in Mongoose?

I have a JSON array that contains objects like this one
{
"InvoiceNo": "FA 2019/1",
"Period": "01",
"DocumentTotals": {
"TaxPayable": "26.94",
"NetTotal": "117.16",
"GrossTotal": "144.10"
},
"WithholdingTax": {
"WithholdingTaxAmount": "0.00"
}
},
I want to sum the GrossTotal of the various objects and group it by Period.
I tried with the following code:
saftFileController.revenuePerMonth = function (req, res) {
Saft.find().exec(function (err, fileContent) {
if (err) {
console.log(err);
} else {
const JSONObject = JSON.parse(JSON.stringify(fileContent));
const sales = JSONObject[3].SalesInvoices.Invoice;
const revenuePerMonth = Saft.aggregate([
{
$group: {
Period: sales.Period,
revenue: {
$sum: "$GrossTotal",
},
},
},
]);
res.json({ revenue: revenuePerMonth });
}
});
};
But the output wasn´t the desired one. What I am doing wrong? This was the output:
{
"revenue": {
"_pipeline": [
{
"$group": {
"revenue": {
"$sum": "$GrossTotal"
}
}
}
],
"options": {}
}
}
Here are some printscreens of my Database
https://snipboard.io/QOfiYz.jpg
https://snipboard.io/72LSRC.jpg
Did this and now returns the Period but it is ignoring the sum because it is a string type.How can I convert?
saftFileController.revenuePerMonth = function (req, res) {
Saft.aggregate([
{
$group: {
_id: "$SalesInvoices.Invoice.Period",
revenue: {
$sum: "SalesInvoices.Invoice.DocumentTotals.GrossTotal",
},
},
},
]).exec(function (err, fileContent) {
if (err) {
console.log("Error: ", error);
} else {
res.json({ revenuePerMonth: fileContent });
}
});
};
You should pass the MongoDB expression what you want to group it by as _id in the $group stage (documentation). The $sum expression should contain the full path as well.
$group: {
_id: '$Period',
revenue: {
$sum: "$DocumentTotals.GrossTotal",
},
},
aggregate accepts a callback, or returns a Promise just like when you use Saft.find()
Saft.aggregate([/* ... */]).exec(function (err, result) {
/* use result here */
})

append to list if exist or add list in dynamoDB

I have a product table in DynamoDB which has some items. Now I need to add list of buyers to the product which can grow i.e. append to list. It works for if I have an empty list or a list with some items in the table item but for the first addition it throws an error. Is there any way to check if list exists then append else add a list. here is my code
let params = {
TableName: "product",
ExpressionAttributeNames: {
"#Y": "buyer"
},
ExpressionAttributeValues: {
":y": ["PersonXYZ"]
},
Key: {
id: 'Hy2H4Z-lf'
},
UpdateExpression: "SET #Y = list_append(#Y,:y)"
};
updateItemInDDB(params).then((data) => {
res.status(200).send(data);
}, err => {
console.log(err);
res.sendStatus(500);
});
UpdateItemInDDB is just a function which takes a params and run dnamodb code on it. I am using javascript sdk for DynamoDB with Document Client.
var params = {
TableName: "user",
Key: {
"user_id": {
S: user_id
}
},
UpdateExpression: "SET #ri = list_append(if_not_exists(#ri, :empty_list), :vals)",
ExpressionAttributeNames: {
"#ri": "images"
},
ExpressionAttributeValues: {
":vals": {"L": [{
"S": "dummy data"
}]},
":empty_list": {"L": []}
},
ReturnValues: 'ALL_NEW'
};
":empty_list": {"L": []}
this is important if you want to set empty list, otherwise it will give below exception.
"errorMessage": "ExpressionAttributeValues contains invalid value: Supplied AttributeValue is empty, must contain exactly one of the supported datatypes for key :empty_list",
"errorType": "ValidationException"
EDIT: Nest the conditional expressions
You could run SET append_list with a ConditionalExpression that the attribute does exist, then if that fails run SET with a ConditinalExpression that the attribute does not exist.
let params1 = {
TableName: "product",
ExpressionAttributeNames: {
"#Y": "buyer"
},
ExpressionAttributeValues: {
":y": ["PersonXYZ"]
},
Key: {
id: 'Hy2H4Z-lf'
},
ConditionExpression: "attribute_exists(buyer)",
UpdateExpression: "SET #Y = list_append(#Y,:y)"
};
updateItemInDDB(params1).then((data) => {
res.status(200).send(data);
}, err => {
console.log(err);
let params2 = {
TableName: "product",
ExpressionAttributeNames: {
"#Y": "buyer"
},
ExpressionAttributeValues: {
":y": ["PersonXYZ"]
},
Key: {
id: 'Hy2H4Z-lf'
},
ConditionExpression: "attribute_not_exists(buyer)",
UpdateExpression: "SET #Y = (#Y,:y)"
};
updateItemInDDB(params2).then((data) => {
res.status(200).send(data);
}, err => {
console.log(err);
res.sendStatus(500);
});
});

DynamoDB: Appending an element to a list using Node.js

This doesn't work. Is there another way to do this? cord is a list to which I want to add a map.
var params5 = {
TableName: 'rides',
Key: {
'rid': data2.Items[0].rid
},
UpdateExpression: 'add cord :x',
ExpressionAttributeValues: {
':x': [{date: secondStartDate.toString(), latitude: xcorpassed, longitude: ycorpassed}]
},
ReturnValues: 'UPDATED_NEW'
}
docClient.update(params5, function (err5, data5) { ... }
Instead of ADD, you could use SET with the list_append function (in general, AWS recommends using SET rather than ADD):
(NOTE: The list_append function name is case-sensitive)
var params = {
TableName: "rides",
Key: {
"rid": data2.Items[0].rid
},
UpdateExpression: "SET #c = list_append(#c, :vals)",
ExpressionAttributeNames: {
"#c": "cord"
},
ExpressionAttributeValues: {
":vals": [{date: secondStartDate.toString(), latitude: xcorpassed, longitude: ycorpassed}]
},
ReturnValues: "UPDATED_NEW"
}
docClient.update(params, function (err, data) {
if (err) console.log(err);
else console.log(data);
}
Without seeing the error code it throws it looks like you should change add to set and don't forget the = sign.
var params5 = {
TableName: 'rides',
Key: {
'rid': data2.Items[0].rid
},
UpdateExpression: 'set cord = :x',
ExpressionAttributeValues: {
':x': [{date: secondStartDate.toString(), latitude: xcorpassed, longitude: ycorpassed}]
},
ReturnValues: 'UPDATED_NEW'
}
docClient.update(params5, function (err5, data5) {

Determine when async execution is finished

I have to process an array of entries that requires to perform to async tasks for each file entry: getFile and uploadResult both are async task. My question is how can I know when the array doc.entries is being processed using an async library like asyncjs. The code below is just an illustration of what I am trying to accomplish.
var doc = {
version: '1.7',
entries: [{
date: '11/11/10',
files: [{
name: 100,
executable: false
},
{
name: 101,
executable: false
}]
},
{
date: '11/12/10',
files: [{
name: 200,
executable: false
},
{
name: 201,
executable: false
}]
},
{
date: '11/13/10',
files: [{
name: 300,
executable: false
}]
},
{
date: '11/14/10',
files: [{
name: 400,
executable: false
}]
}]
};
doc.entries.map(function(entry){
entry.files.map(function(file){
getFile(file, function(err, result){
if(err){
throw Error(err)
}
uploadResult(result, function(err, status){
WriteOnDb(file.name, status, function(err, result){ ... });
});
})
});
});
How can I know when the last file is being store on the db and then do something else?
Thanks.
The easiest way is to use promises, or better observables, but you do it with callbacks too - for example you can count how many tasks are in total and how many was finished:
var total = doc.entries
.map(function (entry) {
return entry.files.length;
})
.reduce(function (x, acc) {
return acc + x
}, 0);
var finished = 0;
function finishCallback(err) {
if (err === null) {
/// all async tasks are finished;
}
}
doc.entries.map(function (entry) {
entry.files.map(function (file) {
getFile(file, function (err, result) {
if (err) {
finishCallback(err);
} else {
uploadResult(result, function (err, status) {
WriteOnDb(file.name, status, function (err, result) {
if (err) {
finishCallback(err);
} else {
finished += 1;
if (finished === total) finishCallback(null);
}
});
});
}
})
});
});

Javascript variable scope when mongoose query

I'm working with node.js, mongoose and foursquare API.
foursquare.getVenues(params, function(err, venues) {
if(err) return res.json(JSON.stringify({status: 'error', returnData: err}));
// variable initialization
var rooms = [];
var vanueItem;
// iterate foursquare return list (venue item)
venues.response.venues.forEach(function(item) {
Room.aggregate(
[
{ "$group": {
"_id": '$mobileUser.genderType',
"genderTypeCount": { "$sum": 1 }
}}
],
function(err,result) {
if(err) return res.json(JSON.stringify({status: 'error', returnData: err}));
// build it to return after
vanueItem =
{
id: item.id,
name: item.name,
description: item.description,
contact: item.contact.formattedPhone,
lat: item.location.lat,
lng: item.location.lng,
distance: item.location.distance,
city: item.location.city
};
// insert it into venue array
rooms.push(vanueItem);
}
);
});
return res.json(JSON.stringify({ status: 'success', returnData: rooms }));
});
I'm having a problem with rooms array. When I remove the 'Room.aggregate' query, works fine (all rooms was ok), but when I use the aggregate, the return function gives me empty room.
I already tried remove var from 'var rooms = [];'
Room.aggregate is asynchronous function, if you want iterate over asynchronous function you can use async library, like this
var async = require('async');
foursquare.getVenues(params, function(err, venues) {
if (err) return res.json(JSON.stringify({
status: 'error',
returnData: err
}));
var rooms = [];
var vanueItem;
async.each(venues.response.venues, function (item, next) {
Room.aggregate(
[{
"$group": {
"_id": '$mobileUser.genderType',
"genderTypeCount": {
"$sum": 1
}
}
}],
function(err, result) {
if (err) {
return next(err);
}
// build it to return after
vanueItem = {
id: item.id,
name: item.name,
description: item.description,
contact: item.contact.formattedPhone,
lat: item.location.lat,
lng: item.location.lng,
distance: item.location.distance,
city: item.location.city
};
rooms.push(vanueItem);
next(null);
}
);
}, function (err) {
if (err) {
return res.json(JSON.stringify({
status: 'error',
returnData: err
}));
}
return res.json(JSON.stringify({
status: 'success',
returnData: rooms
}));
});
});

Categories

Resources