amazon-web-services - 如果表中不存在具有独占开始键的项目,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 无效的消息。
解决方案
看起来您想根据值返回项目。如果该值不存在,那么您希望有一个空的结果集。这可以通过 Java V2 DynamoDbTable对象的scan方法实现:
对于此解决方案,一种方法是扫描 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);
}
}
推荐阅读
- graphql - “文件”类型的 GraphQL 错误字段“图像”必须具有子字段选择。您的意思是“图像 { ... }”吗?
- ansible - 使用 loop/with_item 构建变量列表
- python - 使用第三个过滤列从另一列添加新列
- node.js - 来自 Lambda Node JS 的多个 Dynamo DB 调用
- html - 使用正则表达式从 R 中删除不需要的 html 标签
- c# - 加载时如何将 TagBuilder 添加到 View
- java - Arrays.asList() 的运行时类是什么
- r - 使用 ggplot 在不同时间点为多个组绘制多个密度内核(面积 = 1)
- java - Gradle编译:找不到包
- sql - 按子句排序与 Excel VBA 中的 distinct 冲突?