0
votes

I am trying to develop a skill where Alexa will read out the information that is within a DynamoDB table that is on the date the user has specified. I have managed to query a DynamoDB table using nodejs within Lambda and am able to return all items which have a particular date. See code below:

function queryDynamoDate_multiple() {
const startdate = this.attributes['startdate'];


var say = '';
var params = {
        TableName: 'RegalCinema',
        KeyConditionExpression: "#date = :yymmdd and #time between :time1 and :time2",
        ExpressionAttributeNames:{
        "#date": "date",
    "#time": "time"

        },
        ExpressionAttributeValues: {
        ":yymmdd":startdate,
    ":time1":'0',
    ":time2":'2'
}};

  readDynamoItem(params, myResult=>{


        say = myResult;

        say = 'you asked,. The answer is: ' + myResult;

        this.response.speak(say).listen('try again');
        this.emit(':responseReady');


       });

    }

.

function readDynamoItem(params, callback) {
var title = [];
var time = [];
var noofitems = 0;
let speechOutput = "";

    docClient.query(params, (err, data) => {
        if (err) {
            this.emit(':tell', 'Test Error');
        } else {
            console.log("Query succeeded.");
            data.Items.forEach(function(item) {
                console.log(" -", item.title + ": ");
                noofitems = noofitems + 1;
                title[noofitems] = item.title;
                time[noofitems] = item.time;

    });

        for (var l = 1; l <= noofitems ; l++){
        if ( l== noofitems){
            speechOutput = speechOutput +" and "+ title[l] + " at " + time[l] + ". ";
        } else if ( l == 1) {
            speechOutput = speechOutput + title[l] + " at " + time[l];
        } else {
            speechOutput = speechOutput + ", " + title[l] + " at "+ time[l];
        } 
}

callback(speechOutput)
        }
    });

}

I would now like to progress and return all items for multiple days (up to a maximum of 7 days). As you can only query the primary partition key in the table with 'equals' rather than 'between' two values. I suspect the only option I have is to run this function multiple times with different dates for params. However, I am struggling to do this and after doing some reading I believe it's due to the asynchronous nature of the function.

I need to loop through this function a set number of times (between 1 and 7) and add one to the date each time it is run. Ideally I would like to store the title in one array and the time in another (as I am already doing). I have no problem manipulating the date value my issue is returning the results from one run of the function and putting them into an array that has already been populated from a previous run of the function.

I hope that makes sense. Any help or guidance would be greatly appreciated.

1

1 Answers

0
votes

You seem to have date as a partition key and time as a range key.

Options:

  • Query multiple times, using each date (you have already suggested this)
  • Add a new datetime attribute, then use a scan instead of a query to return the datetime between two values. This will evaluate every row in the table, but since that sounds like what you need to do, this would be a good approach
  • If there is a different natural partition key (i.e. you only want to query part of the table), you could change your partition key and make datetime the range key instead.