DynamoDbException:条件的长度只能为 1 或 2

Pra*_*ara 11 amazon-web-services amazon-dynamodb

我有 SQL 背景,对 Dynamodb 非常陌生。我有一个像这样的表:

-----------------------------------------------------------
 | dbId | genId | colData | deviceId | updateOn | params |
-----------------------------------------------------------
 |      |       |         |          |          |        |
 ----------------------------------------------------------
Run Code Online (Sandbox Code Playgroud)

dbId是主键,genId是排序键。deviceId我在和中创建了两个本地二级索引updateOn。在 SQL 中我可以从表中查询:

String dbId  = "151/2020-21";
int deviceId = 1001;
long updOn   = 1608456211308;
String query = "select * from tableName where dbId = '"+dbId+"' and deviceId != "+deviceId+" and updateOn > " + updOn;
Run Code Online (Sandbox Code Playgroud)

在 DynamoDb 中,我的 keyConditionExpression 是dbId = :dbId and updateOn > :updateOn and deviceId != :deviceId:它给了我错误:

DynamoDbException: Invalid KeyConditionExpression: Syntax error; token: "!", near: "deviceId !="
Run Code Online (Sandbox Code Playgroud)

我删除了'!'这个:dbId = :dbId and updateOn > :updateOn and deviceId = :deviceId。它给了我错误:

DynamoDbException: Conditions can be of length 1 or 2 only
Run Code Online (Sandbox Code Playgroud)

如何在 Dynamodb 中执行我想要的查询?我应该如何设计 Dynamodb 表(我的意思是主键、索引等),以便获得相同的 sql 类似结果?

Wil*_*ian 16

当涉及到query()dynamoDb 时,建议仅指定 中的分区键和排序键KeyConditionExpression

因此,如果您想query()在更多条件下执行,您应该考虑FilterExpression. 例如:

const params = {
    TableName: 'table-name',
    KeyConditionExpression: 'pk = :pk AND sk = :sk',
    FilterExpression: 'dbId = :dbId and updateOn > :updateOn and deviceId != :deviceId',
    ExpressionAttributeValues: {
      ':pk': '12345',
      ':sk': 'lorem-ipsum',
      ':dbId': '0987654321',
      ':updateOn': '2022-06-25',
      ':deviceId': '123',
    },
  }

  const docClient = new AWS.DynamoDB.DocumentClient();
  const result = await docClient.query(params).promise();
Run Code Online (Sandbox Code Playgroud)


Abd*_*eez 10

现在,您遇到错误“条件的长度只能为 1 或 2”的原因是因为您在 KeyConditionExpression 中指定了 3 个条件。请仅指定分区键和排序键。

最后,您不需要为此目的创建 LSI。您可以对原表进行同样的操作,或者需要添加全局二级索引,这可以帮助您实现仅两个条件的查询。

如前所述,“KeyConditionExpression”中包含的属性应该只是您的哈希键,与您的基表架构相匹配。如果您想查询所有,那么这是不可能的,因为按照 AWS 文档的建议,在任何情况下都不会有排序键。

  • 我已经切换回 RDBMS 并解决了问题。谢谢@Abdul Moeez (3认同)
  • 奇怪的是,即使不可能,我实际上也可以在 AWS Dynamodb 控制台上根据 3 个条件执行查询 (2认同)