I am trying to perform pagination on a simple DynamoDB table for queries by date range, and had hoped to coerce the LastEvaluatedKey into a "hasMoreResults" boolean value for my front end to consume, but now see that a non-empty LastEvaluatedKey can sometimes appear on results even when the number of items within the date range does not exceed my LIMIT. Does this mean that I will always need to perform a subsequent query that will return no additional items?
My table looks something like:
[
{PK: "john", SK: "2021-01-01:08:00", amount: 1},
{PK: "john", SK: "2021-01-01:20:00", amount: 2},
{PK: "john", SK: "2021-01-02:08:00", amount: 3},
{PK: "john", SK: "2021-01-02:20:00", amount: 4},
{PK: "john", SK: "2021-01-03:08:00", amount: 5},
{PK: "john", SK: "2021-01-03:20:00", amount: 6}
...and on for all of January
];
Using the JavaScript DocumentClient, my query looks like:
async function getEntriesByDate({name, startDate, endDate, limit, sort}) {
return await docClient.query({
TableName: "someTableName",
KeyConditionExpression: "#pk = :pk and #sk Between :startDate And :endDate",
ExpressionAttributeNames: {
"#pk": "PK",
"#sk": "SK"
},
ExpressionAttributeValues: {
":pk": name,
":startDate": startDate,
":endDate": endDate
},
ScanIndexForward: sort === "asc",
Limit: limit
}).promise();
}
If I call the function with the end date exactly matching the date of the fourth item and a LIMIT of 4:
getEntriesByDate({name: "john", startDate: "2021-01-01:08:01", endDate: "2021-01-02:20:01", limit: 4, sort:"asc"});
I get the following result:
{
"Items": [
{"PK": "john", "SK": "2021-01-01:08:00", "amount": 1},
{"PK": "john", "SK": "2021-01-01:20:00", "amount": 2},
{"PK": "john", "SK": "2021-01-02:08:00", "amount": 3},
{"PK": "john", "SK": "2021-01-02:20:00", "amount": 4 }
],
"Count": 4,
"ScannedCount": 4
}
Great, there's no LastEvaluatedKey. which is what I expect. But if I call the function with the same args except adding a minute to the end date, I get:
{
"Items": <same as in last query, which is expected>,
"Count": 4,
"ScannedCount": 4,
"LastEvaluatedKey": {
"SK": "2021-01-02:20:00",
"PK": "john"
}
}
and LastEvaluatedKey
does appear, even though there are no additional items that satisfy the query. Is there an idiomatic solution to this problem? Is a subsequent query, perhaps using ExclusiveStartKey
, necessary inside my function in order to secure a reliable hasMoreResults
value?