我正在尝试使用辅助全局索引查询Dynamodb表,并且正在获取java.lang.IllegalArgumentException:查询表达式非法:在查询中未找到哈希键条件。我要做的就是在不考虑键的情况下获取所有时间戳大于某个值的项目。时间戳记不是键或范围键的一部分,因此我为其创建了全局索引。
有人知道我可能会缺少什么吗?
表定义:
{
AttributeDefinitions:[
{
AttributeName:timestamp,
AttributeType:N
},
{
AttributeName:url,
AttributeType:S
}
],
TableName:SitePageIndexed,
KeySchema:[
{
AttributeName:url,
KeyType:HASH
}
],
TableStatus:ACTIVE,
CreationDateTime: Mon May 12 18:45:57 EDT 2014,
ProvisionedThroughput:{
NumberOfDecreasesToday:0,
ReadCapacityUnits:8,
WriteCapacityUnits:4
},
TableSizeBytes:0,
ItemCount:0,
GlobalSecondaryIndexes:[
{
IndexName:TimestampIndex,
KeySchema:[
{
AttributeName:timestamp,
KeyType:HASH
}
],
Projection:{
ProjectionType:ALL,
},
IndexStatus:ACTIVE,
ProvisionedThroughput:{
NumberOfDecreasesToday:0,
ReadCapacityUnits:8,
WriteCapacityUnits:4
},
IndexSizeBytes:0,
ItemCount:0
}
]
}
代码
Condition condition1 = new Condition().withComparisonOperator(ComparisonOperator.GE).withAttributeValueList(new AttributeValue().withN(Long.toString(start)));
DynamoDBQueryExpression<SitePageIndexed> exp = new DynamoDBQueryExpression<SitePageIndexed>().withRangeKeyCondition("timestamp", condition1);
exp.setScanIndexForward(true);
exp.setLimit(100);
exp.setIndexName("TimestampIndex");
PaginatedQueryList<SitePageIndexed> queryList = client.query(SitePageIndexed.class,exp);
最佳答案
这不是Amazon DynamoDB上的全局二级索引(GSI)的工作方式。要查询GSI,您必须指定其哈希键的值,然后您可以按范围键进行过滤/排序-就像使用主键一样。这正是异常试图告诉您的内容,也是您在documentation page for the Query
API上可以找到的内容:
将GSI视为行为几乎与主键完全相同的另一个键(主要区别在于它是异步更新的,并且您最终只能对GSI执行一致的读取操作)。
创建GSI时,请引用Amazon DynamoDB全局二级索引文档页面以获取指南和最佳实践:http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GSI.html
实现所需目标的一种可能方法是将虚拟属性限制为有限的少量可能值,在该虚拟属性上创建带有散列键的GSI,并在时间戳上创建范围键。查询时,您需要为虚拟哈希键属性上的每个可能值发出一个Query API调用,然后将结果合并到应用程序中。通过将dummy属性限制为单例(即,具有单个元素的Set,即常量值),您只能发送一个Query API调用,并且直接获取结果数据集-但请记住,这会导致您遇到与热分区有关的问题,并且可能会遇到性能问题!同样,请引用上面链接的文档以了解最佳做法和一些模式。
关于java - 查询仅具有次要全局索引的Dynamodb表,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/23621104/