Unable to query between dates in DynamoDB from NodeJS Lambda - node.js

I'm having some issues trying to query between dates for a dynamboDB table using NodeJS
I'm trying to query for the data in the data between the dates in the actualReadDate column and get these columns back: meterName, meterNumber, actualReadDate,actualReadTime
I've tried a few different things I've found online, latest attempt is below
async function scanForResults(){
try {
var params = {
TableName: 'MeterReadSubmission-dev',
keyConditionExpression : 'actualReadDate between :from and :to',
ProjectionExpression : 'meterName, meterNumber, actualReadDate,actualReadTime',
ExpressionAttributeValues: {
":from": startDate,
":to": endDate
}
};
var result = await docoClient.query(params).promise()
console.log("Retrieved data: ");
console.log(JSON.stringify(result))
} catch (error) {
console.error(error);
}
}
scanForResults()
The startDate and endDate variables are declared further above with the same format as the dates stored in DynamoDB
I looked at this link: Query DynamoDB between certain dates -NodeJs
But still just can't get it to work. Thanks in advance

Related

NODE.js Lambda dynamodb documentClient get - returned data is not in [] JSON format. How to return a full JSON document datatype form GET

I'm new to Node.js/AWS lambda. Ive successfully created several documentClient QUERY functions that return a single or multiple item JSON Document in this format:
[
{
"name": "andy",
"color": "purple",
"snack": "oreos"
}
]
When I use documentClient GET and get back my single record its in THIS format, which is not playing well with the client code (apple / ios swift)
{
"name": "andy",
"color": "purple",
"snack": "oreos"
}
I'm hopign i can change the format returned from documentClient.get() to include the fill JSON document format including leading and trailing brackets .. []
I am a node.js & aws.lambda and documentClient novice, so apologies if this is a very basic question....
provided in above text
If I understood well, you're receiving an object instead of a array.
You can use the scan function to retrieve an array of results:
var params = {
TableName : 'Table',
FilterExpression : 'Year = :this_year',
ExpressionAttributeValues : {':this_year' : 2015}
};
var documentClient = new AWS.DynamoDB.DocumentClient();
documentClient.scan(params, function(err, data) {
if (err) console.log(err);
else console.log(data);
});
Or you can transform the result to array:
const document = await documentClient.get({
TableName: "table-of-example",
Key: {
id: "id-of-example"
}
});
return [data]
Please read the document to understand more how the document dynamodb sdk works: https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/DynamoDB/DocumentClient.html#scan-property

Issue with date range on nodeJS

I have issues while filtering data from mongodb using nodejs and nextjs.
I am not getting some of the data stored in the database especially if the moment is not this month.
My Routes:
module.exports.getFulfullmentByDateRange = (params) => {
return Fulfillment.find({ createdOn: { $gte: moment(params.dateFrom).format('YYYY-MM-DD'), $lte: moment(params.dateTo).format('YYYY-MM-DD') } }).then(fulfillment => {
return fulfillment
})
}
This only allows me to filter selected data. What I'm trying to achieve is to get all data using the selected range from the from and to datetime picker.

How update (using Nodejs) a second table (DynamoDB) into a lambda function using some values from 2nd table?

I'm writing a lambda function that update a second table when there is an insert on the first table. Both tables are in DynamoDB. When an insert occurs in the first table a lambda function is triggered to update another table based on some values from the new record.
The lambda function is on Nodejs
I do not know exactly how to write the update statement since I have to use the value store in the second table and sum with the new value and update. What I want to do is something like this:
update table1 set campo1 = campo1 + newValue
I am not sure how to do it in NodeJs + DynamoDB.
This is the function:
const AWS = require('aws-sdk');
const documentClient = new AWS.DynamoDB.DocumentClient();
exports.getCalculos = function(event, context, callback){
let columnName = "";
let numPersonas = 0;
let domainIn = "";
event.Records.forEach((record) => {
// I just one the new records inserted
if (record.eventName == 'INSERT') {
// I read all the values and storage into newRecord
const newRecord = record.dynamodb.NewImage;
// I get the key from the new record to be
// used in the second table
domainIn = newRecord.Domain;
// I check some conditions from the new record
// to see which column I will update in the second table
// columns to update are alwayd different
if((newRecord.puerta1.S == "pass") && (newRecord.puerta2.S == "pass")){
columnName = "escape";
}
if((newRecord.puerta1.S == "close") && (newRecord.puerta2.S == "close")){
columnName = "atrapado";
}
// I get the number from the new record
numPersonas = newRecord.count;
// Then base on an ID from the new record,
// I want to update another field into another table
// It means, sum both values
const params = {
TableName :"SummaryByDomain",
Key:{
"Domain": domainIn
},
UpdateExpression: "set #field2 = :numPersonas",
ExpressionAttributeNames:{
"#field2":columnName
},
ExpressionAttributeValues: {
":numPersonas": numPersonas
},
ReturnValues:"UPDATED_NEW"
};
documentClient.update(params, function(err, data) {
if (err) {
console.error("Unable to update item. Error JSON:", JSON.stringify(err, null, 2));
} else {
console.log("UpdateItem succeeded:", JSON.stringify(data, null, 2));
}
});
}
});
};
Thanks #LostJon for your answer. callback wasn't the issue.
I just need how to update the filed using the same value.
I found it and solved it.
I used:
UpdateExpression: "ADD #field2 :numPersonas",
In this case the ADD works as a math operator if values are numeric.
now it's working good

How to query the data with selected date range in CloudBoost

I want to fetch the records from the CloudTable with particular date range say from : startDate to endDate
We can query all columns including DateTime type in a CloudTable. There are several condition you can add to your query like lessThan, greaterThan etc.
In this case, you can use the following query -
var query = new CB.CloudQuery("TableName");
query.lessThan('dateColumns',"15-12-2016");
query.greaterThan('dateColumns',"15-06-2017");
query.find({
success: function(list) {
//list is an array of CloudObjects
},
error: function(error) {
}
});
Hope it helps.Happy Coding :)

AWS DynamoDB Node.js scan- certain number of results

I try to get first 10 items which satisfy condition from DynamoDB using lambda AWS. I was trying to use Limit parameter but it is (basis on that website)
https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/DynamoDB.html#scan-property
"maximum number of items to evaluate (not necessarily the number of matching items)".
How to get 10 first items which satisfy my condition?
var AWS = require('aws-sdk');
var db = new AWS.DynamoDB();
exports.handler = function(event, context) {
var params = {
TableName: "Events", //"StreamsLambdaTable",
ProjectionExpression: "ID, description, endDate, imagePath, locationLat, locationLon, #nm, startDate, #tp, userLimit", //specifies the attributes you want in the scan result.
FilterExpression: "locationLon between :lower_lon and :higher_lon and locationLat between :lower_lat and :higher_lat",
ExpressionAttributeNames: {
"#nm": "name",
"#tp": "type",
},
ExpressionAttributeValues: {
":lower_lon": {"N": event.low_lon},
":higher_lon": {"N": event.high_lon}, //event.high_lon}
":lower_lat": {"N": event.low_lat},
":higher_lat": {"N": event.high_lat}
}
};
db.scan(params, function(err, data) {
if (err) {
console.log(err); // an error occurred
}
else {
data.Items.forEach(function(record) {
console.log(
record.name.S + "");
});
context.succeed(data.Items);
}
});
};
I think you already know the reason behind this: the distinction that DynamoDB makes between ScannedCount and Count. As per this,
ScannedCount — the number of items that were queried or scanned,
before any filter expression was applied to the results.
Count — the
number of items that were returned in the response.
The fix for that is documented right above this:
For either a Query or Scan operation, DynamoDB might return a LastEvaluatedKey value if the operation did not return all matching items in the table. To get the full count of items that match, take the LastEvaluatedKey value from the previous request and use it as the ExclusiveStartKey value in the next request. Repeat this until DynamoDB no longer returns a LastEvaluatedKey value.
So, the answer to your question is: use the LastEvaluatedKey from DynamoDB response and Scan again.

Resources