首页 > 解决方案 > 如果表中不存在具有独占开始键的项目,DynamoDB 扫描会返回什么?

问题描述

我正在尝试为我的 API 实现分页。我有一个带有简单主键的 DynamoDB 表。

由于 DynamoDB scan() 操作中的 ExclusiveStartKey 只不过是之前在 scan 操作中获取的最后一个项目的主键,我想知道如果我使用不存在的 ExclusiveStartKey 执行 scan(),DynamoDB 会返回什么桌子?

# Here response contains the same list of items for the same 
# primary key passed to the scan operation

response = table.scan(ExclusiveStartKey=NonExistentPrimaryKey)

我希望 DynamoDB 不返回任何项目(如果我的这个假设有问题,请纠正我),即扫描应该从 ExclusiveStartKey 恢复,如果它存在于表中。如果不是,它应该不返回任何项目。

但我确实看到发生的是,scan() 仍然返回项目。当我给出相同的不存在的主键时,它会不断向我返回一个从同一项目开始的列表。

DynamoDB 是否只是在 ExclusiveStartKey 上应用哈希函数,并根据该哈希的结果决定它必须从哪个分区开始返回项目或其他东西?

# My theory as to what DynamoDB does in a paginated scan operation
partitionId = dynamodbHashFunction(NonExistentPrimaryKey)

return fetchItemsFromPartition(partitionId)

我的最终目标是,当用户提供无效的 ExclusiveStartKey(即不存在的主键)时,我想什么都不返回,甚至更好,返回 ExclusiveStartKey 无效的消息。

标签: amazon-web-servicesamazon-dynamodb

解决方案


看起来您想根据值返回项目。如果该值不存在,那么您希望有一个空的结果集。这可以通过 Java V2 DynamoDbTable对象的scan方法实现:

https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/DynamoDbTable.html

对于此解决方案,一种方法是扫描 AmazonDB 表并根据特定列的值(包括键)返回结果集。您可以使用Expression对象。这使您可以设置要在结果集中返回的值。

例如,这里是返回日期列为 2013-11-15 的所有项目的 Java 逻辑。如果没有符合此条件的项目,则不退回任何项目。无需预先检查等。您需要正确设置ScanEnhancedRequest

public static void scanIndex(DynamoDbClient ddb, String tableName, String indexName) {

        System.out.println("\n***********************************************************\n");
        System.out.print("Select items for "+tableName +" where createDate is 2013-11-15!");

        try {
            // Create a DynamoDbEnhancedClient and use the DynamoDbClient object.
            DynamoDbEnhancedClient enhancedClient = DynamoDbEnhancedClient.builder()
                    .dynamoDbClient(ddb)
                    .build();

            // Create a DynamoDbTable object based on Issues.
            DynamoDbTable<Issues> table = enhancedClient.table("Issues", TableSchema.fromBean(Issues.class));

            // Setup the scan based on the index.
            if (indexName == "CreateDateIndex") {
                System.out.println("Issues filed on 2013-11-15");

                AttributeValue attVal = AttributeValue.builder()
                        .s("2013-11-15")
                        .build();

                // Get only items in the Issues table for 2013-11-15.
                Map<String, AttributeValue> myMap = new HashMap<>();
                myMap.put(":val1", attVal);

                Map<String, String> myExMap = new HashMap<>();
                myExMap.put("#createDate", "createDate");

                Expression expression = Expression.builder()
                        .expressionValues(myMap)
                        .expressionNames(myExMap)
                        .expression("#createDate = :val1")
                        .build();

                ScanEnhancedRequest enhancedRequest = ScanEnhancedRequest.builder()
                        .filterExpression(expression)
                        .limit(15)
                        .build();

                // Get items in the Issues table.
                Iterator<Issues> results = table.scan(enhancedRequest).items().iterator();

                while (results.hasNext()) {
                    Issues issue = results.next();
                    System.out.println("The record description is " + issue.getDescription());
                    System.out.println("The record title is " + issue.getTitle());
                }
            }

        } catch (DynamoDbException e) {
            System.err.println(e.getMessage());
            System.exit(1);
        }
    }
  

推荐阅读