查询DynamoDB

时间:2013-10-21 18:59:19

标签: java amazon-web-services conditional-statements amazon-dynamodb

我有一个带有字母数字字符串作为哈希键的DynamoDB表(例如" d4ed6962-3ec2-4312-a480-96ecbb48c9da")。我需要根据表中的另一个字段查询表,因此我需要我的查询来选择所有键,例如我的字段x在dat x和date y之间。

我知道我需要哈希键上的条件和范围键上的另一个条件,但是我很难编写一个不将我的查询绑定到特定ID的哈希键条件。

我认为我可以根据ID为NOT_NULL来解决冗余条件,但是当我使用它时我得到了错误:

  

不支持查询密钥条件

以下是我正在使用的条件,任何想法如何实现这一目标?

 Condition hashKeyCondition = new Condition()
 .withComparisonOperator(ComparisonOperator.NOT_NULL.toString());

Condition rangeCondition = new Condition()
.withComparisonOperator(ComparisonOperator.BETWEEN.toString())
.withAttributeValueList(new AttributeValue().withS(dateFormatter.print(lastScanTime())), 
new AttributeValue().withS(dateFormatter.print(currentScanTime)));

Map<String, Condition> keyConditions = new HashMap<String, Condition>();
keyConditions.put("userId", hashKeyCondition);
keyConditions.put("lastAccesTime", rangeCondition);

提前感谢所有人的帮助。

5 个答案:

答案 0 :(得分:6)

在DynamoDB中,您可以获得包含3 api的项目:

Scan(灵活但价格昂贵),

Query(不太灵活:你必须指定一个哈希,但要便宜)

GetItem(哈希,如果你的桌子有一个,按范围)

实现目标的唯一方法是:

  1. 使用扫描,速度慢或价格昂贵。

  2. 使用另一个表(B)作为前一个(A)的索引,如:

    B.HASH ='VALUES' B.RANGE =用户ID B.lastAccesTime = lastAccesTime(带有二级索引)

  3. 现在你必须在写入时维护该索引,但是你可以将它与Query操作一起使用, 获取您的userIds。查询B:hash ='VALUES',x和y之间的lastaccessTime,选择userid。

    希望这有帮助。

答案 1 :(得分:2)

NOT_NULL比较运算符对哈希键条件无效。查询的Hash密钥条件的唯一有效运算符是EQ。更多信息可以在这里找到: http://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Query.html

这意味着查询将无法工作,至少在您的表当前构建时。您可以使用“扫描”操作,也可以创建一个单独的表,按日期(哈希)和用户ID(范围)存储数据。

祝你好运!

答案 2 :(得分:2)

我最终扫描了表并强制执行过滤器。

感谢大家抽出时间帮忙!

答案 3 :(得分:0)

您可以添加全局二级索引,例如,日期的年份和月份,并将其设为您的哈希键,该索引的范围键将是您的日期,然后您可以查询某个月内的任何数据范围。它可以帮助您避免昂贵的全扫描。

E.g。

全球二级指数:
哈希键:例如month_and_year&#39; 2014年3月&#39;
范围键:full_date

希望它有所帮助!

答案 4 :(得分:0)

如果要查询除分区键以外的其他内容,则需要创建GSI。扫描在成本和性能方面非常昂贵。