AWS SDK Java DynamoDB - 使用表达式属性名称查询 - 表达式中使用的表达式属性值未定义
AWS SDK Java DynamoDB - Query with Expression Attribute Name - An expression attribute value used in expression is not defined
类似于:I cannot query my dynamodb table from aws lambda due to wrong filterexpression? and
我正在尝试编写一种查询 DynamoDB tables 的方法,使用 Java 中分区键/排序键的部分匹配。
我尝试访问的 DynamoDB table 有一个分区键“Type”(我知道是 DynamoDB 中的受限关键字,但不是我的选择)和一个排序键“Id”。我知道“类型”但不知道完整的 Id,所以我使用 AWS SDK 2.x 源代码研究了查询方法并实现如下所示:
DynamoDBClient dynamoDbClient = DynamoDbClient.builder()
.region(Region.EU_WEST_1)
.credentialsProvider(StaticCredentialsProvider.create(awsCredentials))
.build();
String idKey = "wholeIdKey";
String idValue = "partialIdValue";
String typeValue = "typeValue";
Map<String, String> expressionNames = new HashMap<>();
expressionNames.put("#t", "Type");
QueryRequest request = QueryRequest.builder()
.tableName(tableName)
.keyConditionExpression("begins_with ( " + idKey + ", :" + idValue + " )
AND #t = :" + typeValue)
.expressionAttributeNames(expressionNames)
.build();
QueryResponse response = dynamoDbClient.query(request);
但是,当我 运行 这段代码时,我收到以下错误消息:
Exception in thread "main" software.amazon.awssdk.services.dynamodb.model.DynamoDbException:
Invalid KeyConditionExpression: An expression attribute value used in expression is not defined; attribute value: :typeValue
好像它没有意识到我告诉代码使用表达式属性名称功能将“#t”替换为“Type”(这是 DynamoDB 中的保留关键字)这一事实
有人可以帮忙吗?
编辑:代码参考:
您的 expressionAttributeName 看起来不错,但您忘记为 :typeValue
提供值,因此 dynamoDB 不知道要查找什么。
除了您所做的之外,您还需要添加一个 expressionAttributeValue
,您可以在其中提供适当的值。 See documentation here
名称很好,但是您在两个值前都添加了“:”前缀。这导致在 ExpressionAttributeValues
中查找您未提供的内容。
切勿尝试将动态值直接写入查询字符串。
固定代码供将来任何人使用(感谢@aherve and @MattTimmermans)
DynamoDBClient dynamoDbClient = DynamoDbClient.builder()
.region(Region.EU_WEST_1)
.credentialsProvider(StaticCredentialsProvider.create(awsCredentials))
.build();
String idKey = "wholeIdKey";
String idValue = "partialIdValue";
String typeValue = "typeValue";
String typeKey = "typeKey";
Map<String, String> expressionNames = new HashMap<>();
expressionNames.put("#t", "Type");
expressionNames.put("#i", "Id");
Map<String, AttributeValue> expressionValues = new HashMap<>();
expressionValues.put(":typeName", AttributeValue.builder().s(typeValue).build());
expressionValues.put(":idName", AttributeValue.builder().s(idValue).build());
QueryRequest request = QueryRequest.builder()
.tableName(tableName)
.keyConditionExpression("#t = :typeName AND begins_with ( #i, :idName )")
.expressionAttributeNames(expressionNames)
.expressionAttributeValues(expressionValues)
.build();
response = dynamoDbClient.query(request);
类似于:I cannot query my dynamodb table from aws lambda due to wrong filterexpression? and
我正在尝试编写一种查询 DynamoDB tables 的方法,使用 Java 中分区键/排序键的部分匹配。
我尝试访问的 DynamoDB table 有一个分区键“Type”(我知道是 DynamoDB 中的受限关键字,但不是我的选择)和一个排序键“Id”。我知道“类型”但不知道完整的 Id,所以我使用 AWS SDK 2.x 源代码研究了查询方法并实现如下所示:
DynamoDBClient dynamoDbClient = DynamoDbClient.builder()
.region(Region.EU_WEST_1)
.credentialsProvider(StaticCredentialsProvider.create(awsCredentials))
.build();
String idKey = "wholeIdKey";
String idValue = "partialIdValue";
String typeValue = "typeValue";
Map<String, String> expressionNames = new HashMap<>();
expressionNames.put("#t", "Type");
QueryRequest request = QueryRequest.builder()
.tableName(tableName)
.keyConditionExpression("begins_with ( " + idKey + ", :" + idValue + " )
AND #t = :" + typeValue)
.expressionAttributeNames(expressionNames)
.build();
QueryResponse response = dynamoDbClient.query(request);
但是,当我 运行 这段代码时,我收到以下错误消息:
Exception in thread "main" software.amazon.awssdk.services.dynamodb.model.DynamoDbException:
Invalid KeyConditionExpression: An expression attribute value used in expression is not defined; attribute value: :typeValue
好像它没有意识到我告诉代码使用表达式属性名称功能将“#t”替换为“Type”(这是 DynamoDB 中的保留关键字)这一事实
有人可以帮忙吗?
编辑:代码参考:
您的 expressionAttributeName 看起来不错,但您忘记为 :typeValue
提供值,因此 dynamoDB 不知道要查找什么。
除了您所做的之外,您还需要添加一个 expressionAttributeValue
,您可以在其中提供适当的值。 See documentation here
名称很好,但是您在两个值前都添加了“:”前缀。这导致在 ExpressionAttributeValues
中查找您未提供的内容。
切勿尝试将动态值直接写入查询字符串。
固定代码供将来任何人使用(感谢@aherve and @MattTimmermans)
DynamoDBClient dynamoDbClient = DynamoDbClient.builder()
.region(Region.EU_WEST_1)
.credentialsProvider(StaticCredentialsProvider.create(awsCredentials))
.build();
String idKey = "wholeIdKey";
String idValue = "partialIdValue";
String typeValue = "typeValue";
String typeKey = "typeKey";
Map<String, String> expressionNames = new HashMap<>();
expressionNames.put("#t", "Type");
expressionNames.put("#i", "Id");
Map<String, AttributeValue> expressionValues = new HashMap<>();
expressionValues.put(":typeName", AttributeValue.builder().s(typeValue).build());
expressionValues.put(":idName", AttributeValue.builder().s(idValue).build());
QueryRequest request = QueryRequest.builder()
.tableName(tableName)
.keyConditionExpression("#t = :typeName AND begins_with ( #i, :idName )")
.expressionAttributeNames(expressionNames)
.expressionAttributeValues(expressionValues)
.build();
response = dynamoDbClient.query(request);