使用DynamoDBMapper进行AWS DynamoDB范围扫描

时间:2017-05-24 12:50:31

标签: java amazon-dynamodb aws-sdk nosql

我在使用关系数据库很长一段时间后第一次尝试使用DynamoDB,现在正在更新测试结果以供以后分析,请考虑下表和二级索引

1 2

我一直试图获取给定的testName,测试使用以下Java代码在已知的修订版本中运行:

HashMap<String, Condition> scanMap = new HashMap<>();
scanMap.put("revision", new Condition().withComparisonOperator(ComparisonOperator.BETWEEN).withAttributeValueList(Arrays.asList(new AttributeValue("N:"+String.valueOf(minRev)), new AttributeValue("N:"+String.valueOf(maxRev)))));
scanMap.put("testName", new Condition().withComparisonOperator(ComparisonOperator.EQ).withAttributeValueList(new AttributeValue(Collections.singletonList(testName))));
DynamoDBScanExpression scanExpression = new DynamoDBScanExpression().withScanFilter(scanMap);
scanExpression.setIndexName("testName-revision-index");
List<ValidationReport> reports = getMapper().scan(ValidationReport.class, scanExpression);

我试图删除&#34; N:&#34;没有运气。删除修订表达式将返回所有测试运行,而不限制修订范围

这里有任何帮助

1 个答案:

答案 0 :(得分:1)

所以,似乎我在这里吠叫错误的树,试图使用Scan而不是Query:

  

客户不应使用已弃用的ScanFilter。 List / Map数据类型更适合新的FilterExpression语法。我怀疑问题在于名称中带有“N:”的多值属性;这似乎并不接近有线格式。要使用“新”过滤器表达式,他们应该创建ExpressionAttributeNames和ExpressionAttributeValues来告诉AWS SDK有关过滤器的属性,addExpressionAttributeNamesEntry和addExpressionAttributeValuesEntry。http://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/dynamodbv2/datamodeling/DynamoDBScanExpression.html此外,如果我没有指出,那将是我的疏忽扫描绝对不是此查询的正确API操作;查询是正确的操作。 testName应该与带有KeyConditionExpression的Query一起使用,以将搜索范围缩小到正确的分区,并且应该使用BETWEEN语法将修订版添加到相同的版本中。扫描用于备份和后台操作,在这种情况下,客户的索引架构可以与Query一起使用以缩小搜索范围。注意他们使用Scan;这是一个基本的最佳实践:http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/QueryAndScanGuidelines.html

所以我改用了Query:

    Map<String, AttributeValue> eav = new HashMap<String, AttributeValue>();
    eav.put(":v1", new AttributeValue().withS(testName));
    eav.put(":v2", new AttributeValue().withS(version));
    eav.put(":v3", new AttributeValue().withN(String.valueOf(minRev)));
    eav.put(":v4", new AttributeValue().withN(String.valueOf(maxRev)));

    final DynamoDBQueryExpression<ValidationReport> query = new DynamoDBQueryExpression<>();
    query.withKeyConditionExpression("testName = :v1");
    query.withFilterExpression("buildVersion = :v2 and revision BETWEEN :v3 AND :v4");
    query.setConsistentRead(false);
    query.withExpressionAttributeValues(eav);
    return getMapper().query(ValidationReport.class, query);`

请注意,使用AttributeValue时,以下内容之间存在很大差异:

new AttributeValue().withS("SomeStringValue")
new AttributeValue().withN("SomeNumber")

我缺少的是