【问题标题】:DynamoDb query with filter expression in Java在 Java 中使用过滤器表达式的 DynamoDb 查询
【发布时间】:2020-08-29 17:21:27
【问题描述】:

我在 AWS 中有一个名为 school-data 的 DynamoDb 表。以下是获取所有学校名称的现有代码:

private DynamoDBQueryExpression<School> createQueryBySchoolName(String schoolName) {
    String matchSchoolName = "schoolName = :schoolName";
    Map<String, AttributeValue> schoolNames = new HashMap<>();
    schoolNames.put(":schoolName", new AttributeValue().withS(schoolName));

    return new DynamoDBQueryExpression<School>()
            .withIndexName("schoolName-index")
            .withKeyConditionExpression(matchSchoolName)
            .withExpressionAttributeValues(schoolNames)
            .withConsistentRead(false);
}

上述查询工作正常。但是现在我需要获取所有具有特定学校名称及其地址的学校。所以,下面是表中的 3 列:

id   schoolName  details

详情栏的数据如下:

{
"zone": "North",
"type": "Convent",
"address": {
    "id": "138",
    "street1": "123 Street",
    "street2": "456 Road"
}
}

所以,我需要获取所有名称为“ABC”的学校,地址 street1 为“123 Street”。因此,我将上述查询更新如下:

private DynamoDBQueryExpression<School> createQueryBySchoolName(String schoolName) {
    String matchSchoolName = "schoolName = :schoolName";
    Map<String, AttributeValue> schoolNames = new HashMap<>();
    schoolNames.put(":schoolName", new AttributeValue().withS(schoolName));
    schoolNames.put(":streetName", new AttributeValue().withS("123 Street"));


    return new DynamoDBQueryExpression<School>()
            .withIndexName("schoolName-index")
            .withKeyConditionExpression(matchSchoolName)
            .withFilterExpression("details.address.street1 = :streetName")
            .withExpressionAttributeValues(schoolNames)
            .withConsistentRead(false);
}

但是,这不会返回任何数据。你能告诉我我做错了什么吗?

【问题讨论】:

  • 应该已经工作了,所以我想知道我错过了什么。有多少学校只匹配名称“ABC”(没有对地址进行额外过滤)?如果数量很大,则过滤后响应的第一页可能确实为空。您是否确认您正确阅读了所有结果页面,而不仅仅是第一个?
  • @NadavHar'El 我还没有实现分页。另外,我尝试测试我预计只有 10 条记录的情况,即使这样,响应也是空的。

标签: java filter amazon-dynamodb


【解决方案1】:

您需要为 DynamoDBQueryExpression 设置 HashKeyValues 并添加页数限制

private DynamoDBQueryExpression<School> createQueryBySchoolName(String schoolName) {
String matchSchoolName = "schoolName = :schoolName";
Map<String, AttributeValue> schoolNames = new HashMap<>();
schoolNames.put(":schoolName", new AttributeValue().withS(schoolName));
schoolNames.put(":streetName", new AttributeValue().withS("123 Street"));


return new DynamoDBQueryExpression<Voucher>()
        .withHashKeyValues(schoolName)
        .withIndexName("schoolName-index")
        .withKeyConditionExpression(matchSchoolName)
        .withFilterExpression("details.address.street1 = :streetName")
        .withExpressionAttributeValues(schoolNames)
        .withConsistentRead(false)
        .withLimit(pPageSize);

}

【讨论】:

  • .withHashKeyValues 需要一个 School 对象,而不是您在此处使用的字符串。
  • 另外,我得到这个错误:非法查询表达式:必须指定哈希键条件或键条件表达式,但不能同时指定。
猜你喜欢
  • 2020-10-23
  • 1970-01-01
  • 2018-11-15
  • 2020-09-06
  • 1970-01-01
  • 2020-04-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多