DynamoDB 将 Number 视为 KeyConditionExpression 中的 Map -> 失败

DynamoDB treats Number as Map in KeyConditionExpression -> fails

环境

所以我的 TypeScript CDK 项目中有以下 QueryInput-Object。

const params: QueryInput = {
    TableName: criticalMessagesTableName,
    ProjectionExpression: 'message',
    KeyConditionExpression: 'myId = :myId and #ts BETWEEN :startTimestamp AND :endTimestamp',

    ExpressionAttributeValues: {
        ':myId': { S: myId },
        ':startTimestamp': { N: String(startTimestamp) },
        ':endTimestamp': { N: String(startTimestamp + range - 1) },
    },
    ExpressionAttributeNames: {
        '#ts': 'timestamp',
    },
};

具有以下变量值:

const myId = "some-string-based-partition-key-value";
const startTimestamp = 1630927923544; //ms since epoch value
const range = 60000; // some range in ms

table 将 myId 作为分区键(字符串),将 timestamp 作为排序键(数字)。

问题

当使用 AWS.DynamoDB.DocumentClient 实例执行查询时,我的错误回调函数写入以下日志:

{
"message": "Invalid KeyConditionExpression: Incorrect operand type for operator or function; operator or function: BETWEEN, operand type: M",
"code": "ValidationException",
"time": "2021-09-06T12:18:33.720Z",
"requestId": "M041V4RVD57IGRGNF7P7U15GRNVV4KQNSO5AEMVJF66Q9ASUAAJG",
"statusCode": 400,
"retryable": false,
"retryDelay": 43.99195146574429

}

我从中得知我的 :startTimestamp 和 :endTimestamp 以某种方式被视为地图。但是我不知道为什么。

另外,仅使用 <= 和 > 作为变通方法也是不可能的,因为您只能在 KeyConditionExpression 中为每个键使用一个运算符。

感谢您对此(TS 特定)文档的任何帮助,这方面的内容非常少。

您使用的是 AWS.DynamoDB.DocumentClient,它与同类 AWS.DynamoDB 的主要区别之一是它使用原生 JavaScript 类型,而不是将其包装在 AttributeValue地图。所以你的查询应该是这样的:

const params: QueryInput = {
    // ...
    ExpressionAttributeValues: {
        ':myId': myId,
        ':startTimestamp': startTimestamp,
        ':endTimestamp': startTimestamp + range - 1,
    }

有关更多详细信息,请参阅此处文档客户端的 API 文档(尤其是“编组输入和解组响应数据”部分):https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/DynamoDB/DocumentClient.html