我有一个名为“ product”的DynamoDB表,其全局二级索引位于“ userId”上。主键位于“ id”上。
我正在尝试使用“ userID” GSI上的“ withExclusiveStartKey”来实现分页查询。
但是,当我传递有效的lastId时,出现以下异常:
独占启动键的大小必须与表的键模式相同
(服务:AmazonDynamoDBv2;状态代码:400;错误代码:
ValidationException;要求编号:
822db97e-04a3-4c36-8c72-6008e2693679)
我在这里做错了什么?
public QueryResultPage<Product> findPaged(String userId,int limit,String lastId) {
DynamoDBMapper mapper = new DynamoDBMapper(dynamoDb);
Map<String, AttributeValue> vals = new HashMap<>();
vals.put(":valUserId", new AttributeValue().withS(userId));
DynamoDBQueryExpression<Product> queryExp = new DynamoDBQueryExpression<Product>()
.withKeyConditionExpression("userId = :valUserId")
.withIndexName(ModelConsts.TBL_PRODUCT_GSI_USERID)
.withExpressionAttributeValues(vals)
.withScanIndexForward(false)
.withConsistentRead(false)
.withLimit(limit);
if (lastId != null) {//paging
Map<String, AttributeValue> exclusiveStartKey = new HashMap<String, AttributeValue>();
exclusiveStartKey.put("id", new AttributeValue().withS(lastId));
queryExp = queryExp.withExclusiveStartKey(exclusiveStartKey);
}
QueryResultPage<Product> result = mapper.queryPage(Product.class, queryExp);
return result;
}
最佳答案
GSI原始表的所有键值都应设置为开始键。如果表具有分区键和排序键,则两个键值都应设置为开始键值。
在以下示例中:
1)videos
表具有videoid
作为分区键和category
作为排序键
2)GSI定义为category
作为分区键,而videoid
作为排序键
以下代码通过设置了开始键(即分区键和排序键)的category
值查询GSI。
当我不填充分区或排序键时,我可以重现您的错误。
示例代码:-
public QueryResultPage<VideoDynamoMappingAdapter> findVideosByCategoryUsingGSIAndMapperWithStartKey(
String category) {
DynamoDBMapper dynamoDBMapper = new DynamoDBMapper(dynamoDBClient);
QueryResultPage<VideoDynamoMappingAdapter> queryResult = null;
Map<String, AttributeValue> vals = new HashMap<>();
vals.put(":val1", new AttributeValue().withS(category));
DynamoDBQueryExpression<VideoDynamoMappingAdapter> queryExp = new DynamoDBQueryExpression<VideoDynamoMappingAdapter>()
.withKeyConditionExpression("category = :val1").withIndexName("VideoCategoryGsi")
.withExpressionAttributeValues(vals).withScanIndexForward(false).withConsistentRead(false).withLimit(1);
Map<String, AttributeValue> startKey = new HashMap<>();
startKey.put("videoid", new AttributeValue().withS("2"));
startKey.put("category", new AttributeValue().withS("Thriller"));
queryExp.setExclusiveStartKey(startKey);
queryResult = dynamoDBMapper.queryPage(VideoDynamoMappingAdapter.class, queryExp);
System.out.println("Result size ===>" + queryResult.getResults().size());
System.out.println("Last evaluated key ===>" + queryResult.getLastEvaluatedKey());
for (VideoDynamoMappingAdapter videoDynamoMappingAdapter : queryResult.getResults()) {
System.out.println("Video data ===>" + videoDynamoMappingAdapter.toString());
}
return queryResult;
}
关于pagination - DynamoDB:在全局二级索引上使用“withExclusiveStartKey”进行分页,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40988397/