本文介绍了DynamoDB:使用"withExclusiveStartKey"进行分页;在全球二级指数上的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个名为"product"的DynamoDB表,其全局二级索引位于"userId"上.主键位于"id"上.我正在尝试使用"userID" GSI上的"withExclusiveStartKey"来实现分页查询.但是,当我传递有效的lastId时,出现以下异常:

I have DynamoDB table called "product" with a Global Secondary Index on "userId".Primary Key is on "id".I am trying to implement Querying with pagination using "withExclusiveStartKey" on "userID" GSI.However, I get following exception when I pass a valid lastId:

我在这里做什么错了?

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原始表的所有键值都应设置为开始键.如果该表具有分区键和排序键,则应将两个键值都设置为开始键值.

All the key values of the original table of GSI should be set as start key. If the table has partition key and sort key, then both the key values should be set as start key values.

在下面的示例中:-

1) videos 表中的 videoid 作为分区键,而 category 作为排序键

1) The videos table has videoid as partition key and category as sort key

2)GSI的定义是使用 category 作为分区键,而 videoid 作为排序键

2) The GSI is defined with category as partition key and videoid as sort key

以下代码通过设置了开始键(即分区键和排序键)的 category 值查询GSI.

The below code queries the GSI by category value with start key set (i.e. both partition and sort key).

当我不填充分区或排序键时,我可以重现您的错误.

I can reproduce your error when I don't populate the partition or sort key.

示例代码:-

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;

}

这篇关于DynamoDB:使用"withExclusiveStartKey"进行分页;在全球二级指数上的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-05 13:52