当前位置: 首页 > 知识库问答 >
问题:

如果表中不存在具有独占开始键的项,DynamoDB扫描将返回什么?

钮长恨
2023-03-14

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

由于DynamoDB扫描()操作中的ExclusiveStartKey只不过是扫描操作中读取的最后一项的主键,所以我想知道如果我使用表中不存在的ExclusiveStartKey执行扫描(),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无效。

共有1个答案

濮泳
2023-03-14

看起来您希望基于值返回项目。如果该值不存在,则需要一个空结果集。这可以通过Java V2 DynamoDbTable对象的扫描方法实现:

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

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

例如,这里Java逻辑返回日期列为2013-11-15的所有项。如果没有满足此条件的项目,则不返回任何项目。不需要预先检查等。您需要正确设置扫描增强请求。

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);
        }
    }
  
 类似资料:
  • tldr;-当使用带有DynamoDB查询的伪LastEvaluatedKey进行分页时,在某些情况下它仍然会返回结果。 我正在为一个相当直接的CRUD存储库实现分页。实施的基础是:https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Query.Pagination.html 使用DynamoDBMapper Java

  • 我正在执行对DynamoDB表的扫描,然后我需要将返回项中的相应属性添加到类型的列表中(具有单个构造函数)。代码当前成功扫描DB并返回扫描结果的。然而,由于某种原因,我的迭代似乎返回null。

  • 假设我有一个带有分区键“ID”和范围键“Time”的表,其中包含以下项目: 我只想扫描每个分区中时间值最高的一个项目。所以扫描的结果应该如下所示: DynamoDB的扫描功能是否可能做到这一点?(我想避免全部扫描,自己过滤)。

  • 正如标题所说,我想知道在Amazon DynamoDB中扫描表的最佳方式,通过主键以外的另一个字段进行搜索。 我对此进行了搜索,读了很多书,但我找到了这个解决方案: 这对我来说是可行的,但我也了解到,对性能和定价而言,在表上执行扫描是个坏主意。但是,怎么做呢? > DocumentClient和DynamoDB对象有什么区别? 我总是使用。get()用于在DynamoDB上获取所需内容。这是一种好

  • DynamoDb文档中指定的查询操作: 查询操作仅搜索主键属性值,并支持对键属性值的比较运算符子集以优化搜索过程。 和扫描操作: 扫描操作扫描整个表。您可以指定要应用于结果的过滤器,以在完成扫描后优化返回给您的值。 这是基于性能和成本考虑的最佳选择。

  • 我正在尝试找出存储在一个匹配Redis模式的键列表中的值。我尝试使用以便稍后使用获取所有值,但问题是: 返回所需的键。如何强制查看所有现有键?我得去查lua吗?