AWS DynamoDb:查询与比较运算符匹配的多个项目

时间:2014-07-14 23:23:55

标签: amazon-web-services

说我正在实施优步,我有一个这样的表:

Table: Cars
Row: carId=A, city=SF, driverId=52
Row: carId=B, city=LA, driverId=285
Row: carId=C, city=SF, driverId=547
Row: carId=D, city=SF, driverId=125
Row: carId=E, city=LA, driverId=876
Row: carId=F, city=NY, driverId=92

我有'城市'的全球二级指数。

现在我想运行一个查询,“城市中所有车辆是什么= SF或城市=洛杉矶”。有没有办法使用全局二级索引?

显然,我可以使用Scan并让Dynamo查看每一行,但我希望Query可以更有效地完成。

BTW这是我目前的尝试:

List<AttributeValue> attributeValueList = new ArrayList<>();
String[] cities = {"LA", "SF"};
for (String city : cities) {
    attributeValueList.add(new AttributeValue().withS(city));
}

QueryRequest queryRequest = new QueryRequest()
        .withTableName("Cars")
        .withIndexName("Cars-city-index")
        .withSelect("ALL_ATTRIBUTES");
HashMap<String, Condition> keyConditions = new HashMap<String, Condition>();
keyConditions.put("city", new Condition()
        .withComparisonOperator(ComparisonOperator.IN)
        .withAttributeValueList(attributeValueList));
queryRequest.setKeyConditions(keyConditions);

但是失败并出现错误“尝试条件约束不是可转换操作”:

Caused by: com.amazonaws.AmazonServiceException: Attempted conditional constraint is not an indexable operation (Service: AmazonDynamoDBv2; Status Code: 400; Error Code: ValidationException; Request ID: 9LH0D9K02CAS078M3C06R8T4D7VV4KQNSO5AEMVJF66Q9ASUAAJG)
    at com.amazonaws.http.AmazonHttpClient.handleErrorResponse(AmazonHttpClient.java:820)
    at com.amazonaws.http.AmazonHttpClient.executeHelper(AmazonHttpClient.java:439)
    at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:245)
    at com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient.invoke(AmazonDynamoDBClient.java:2908)
    at com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient.query(AmazonDynamoDBClient.java:1064)

感谢您的帮助!!

1 个答案:

答案 0 :(得分:1)

据我所知,您只能为哈希键运行一个相等条件,无论它们是否是全局二级索引。以下是AWS doc所说的内容:

  

“查询支持一组特定的比较运算符来选择键值。您必须将哈希键属性名称和值指定为相等条件。您可以选择指定第二个条件,引用范围键属性;此条件允许你可以从几个条件运算符中选择“

     

“如果您的表具有一个或多个辅助索引,则可以按查询表的相同方式查询这些索引”

所以我想这里最好的选择是运行两个查询并加入结果。或者,如果您有很多值,则必须使用包含IN比较运算符的过滤器运行扫描。这种问题非常适合NoSQL,在这种情况下你肯定会更好地使用关系数据库。

希望这有帮助