Ash*_*iya 4 pagination amazon amazon-dynamodb
我有名为"product"的DynamoDB表,其中"userId"的全局二级索引.Primary Key在"id"上.我正在尝试使用"userID"GSI上的"withExclusiveStartKey"实现分页查询.但是,当我传递一个有效的lastId时,我得到以下异常:
独占开始密钥必须与表的密钥模式具有相同的大小(服务:AmazonDynamoDBv2;状态代码:400;错误代码:ValidationException;请求ID: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;
}
Run Code Online (Sandbox Code Playgroud)
alb*_*ano 11
我正在为那些尝试exclusiveStartKey 手动构建GSI查询的人写这个答案.独家启动键似乎由3个组件组成:
这似乎没有在任何地方记录,因为你应该只使用lastEvaluatedKey通过调用返回:
setLastEvaluatedKey(queryResult.getLastEvaluatedKey());
Run Code Online (Sandbox Code Playgroud)
接受的答案是正确的,但它给读者留下了一个印象,即密钥只有2个组件,这对我的情况没有帮助.这个描述的解决方案首先在这个GitHub问题中提到过.
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;
}
Run Code Online (Sandbox Code Playgroud)
小智 5
当考虑索引时,最后评估的键由两件事组成。
您可以简单地从 QueryResultPagelast 中 Sysout 最后评估的键 (EvaluatedKeyMap) 并获取模式。
在您的情况下,当您创建 ExclusiveStartKey 时,也添加最后评估的“userId”。ExclusiveStartKey.put("userId", 最后评估的用户id属性值);
前任。
exclusiveStartKey.put("id", new AttributeValue().withS(lastUserId));
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5015 次 |
| 最近记录: |