What is the current method using DynamoDBmapper and DynamoDBQueryExpression to query a global secondary index, sort on Sort Index, and return top n results?
First tried solution shown here: https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/DynamoDBMapper.Methods.html#DynamoDBMapper.Methods.query
However, withKeyConditionExpression no longer exists for DynamoDBQueryExpression. Next, I tried the example shown here: How to query a Dynamo DB having a GSI with only hashKeys using DynamoDBMapper
Which uses setHashKeyValues, but I get the following error: com.amazonaws.mobileconnectors.dynamodbv2.dynamodbmapper.DynamoDBMappingException: Public, zero-parameter hash key property must be annotated with interface com.amazonaws.mobileconnectors.dynamodbv2.dynamodbmapper.DynamoDBHashKey
If i do a scan, I am able to pull results, so I think permissions are correct:
Map<String, AttributeValue> eav = new HashMap<String, AttributeValue>();
eav.put(":val1", new AttributeValue().withS(Leaderboard));
DynamoDBScanExpression scanExpression = new DynamoDBScanExpression()
.withFilterExpression("Leaderboard = :val1") // and Ranking <= :val2")
.withExpressionAttributeValues(eav);
DynamoDBmapper object looks like this. I didn't include any of the primary key attributes from the main table, just this subset.
@DynamoDBTable(tableName = "Users")
public class DynamoLeaderboard implements Serializable {
private String leaderboard;
private String userName;
private int ranking;
public DynamoLeaderboard() {}
@DynamoDBIndexHashKey(globalSecondaryIndexName = "Leaderboard-Ranking-index", attributeName = "Leaderboard")
public String getLeaderboard() {
return leaderboard;
}
public void setLeaderboard(final String leaderboard) {
this.leaderboard = leaderboard;
}
@DynamoDBIndexRangeKey(globalSecondaryIndexName = "Leaderboard-Ranking-index", attributeName = "Ranking")
public int getRanking() {
return ranking;
}
public void setRanking(int ranking) {
this.ranking = ranking;
}
@DynamoDBAttribute(attributeName = "UserName")
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
}
Then the query is called:
final DynamoLeaderboard tmpLeaderboard = new DynamoLeaderboard();
tmpLeaderboard.setLeaderboard("0");
Map<String, AttributeValue> eav = new HashMap<String, AttributeValue>();
eav.put(":val1", new AttributeValue().withS("0"));
DynamoDBQueryExpression<DynamoLeaderboard> queryExpression = new DynamoDBQueryExpression<DynamoLeaderboard>();
queryExpression.withIndexName("Leaderboard-index");
queryExpression.setHashKeyValues(tmpLeaderboard);
queryExpression.withConsistentRead(false);
scanResult = mapper.query(DynamoLeaderboard.class, queryExpression);
Comments on what's causing the zero-property hash key exception? Does it have to do with setting the table main hash key vs the GSI hash key?
Recommendations on the current and correct way to execute queries on GSI?
Much appreciated!