首页 > 解决方案 > 当前使用 DynamoDBmapper 查询 GSI、按排序键排序并返回 n 个结果的方法?

问题描述

当前使用 DynamoDBmapper 和 DynamoDBQueryExpression 查询全局二级索引、对 Sort Index 进行排序并返回 top n 结果的方法是什么?

此处显示的第一个尝试解决方案: https ://docs.aws.amazon.com/amazondynamodb/latest/developerguide/DynamoDBMapper.Methods.html#DynamoDBMapper.Methods.query

但是,DynamoDBQueryExpression 不再存在 withKeyConditionExpression。接下来,我尝试了此处显示的示例: How to query a Dynamo DB has a GSI with only hashKeys using DynamoDBMapper

其中使用 setHashKeyValues,但我收到以下错误:com.amazonaws.mobileconnectors.dynamodbv2.dynamodbmapper.DynamoDBMappingException:公共的零参数哈希键属性必须使用接口 com.amazonaws.mobileconnectors.dynamodbv2.dynamodbmapper.DynamoDBHashKey 进行注释

如果我进行扫描,我可以提取结果,所以我认为权限是正确的:

                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 对象如下所示。我没有包含主表中的任何主键属性,只是这个子集。

@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;
    }
}

然后调用查询:

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);

关于导致零属性哈希键异常的原因的评论?它是否与设置表主哈希键与 GSI 哈希键有关?

关于在 GSI 上执行查询的当前正确方法的建议?

非常感激!

标签: javaandroidamazon-dynamodbdynamodb-queries

解决方案


这是我的方式 :

final Example example = new Example();
example.setID(senderAcid);

final DynamoDBQueryExpression<Example> queryExpression = new DynamoDBQueryExpression<>();

queryExpression.withIndexName("SomeGSIndex")
    .withConsistentRead(false)
    .withProjectionExpression("id,omeOtherData,someOtherFieldName")
    .withHashKeyValues(example);

---------- SortKey 的重要条件

queryExpression.withRangeKeyCondition("sortKeyField",
    new Condition()
        .withComparisonOperator(ComparisonOperator.EQ)
        .withAttributeValueList(new AttributeValue().withS(sortKeyValue)));

- - - - 最后

mapper.query(Example.class, query);

推荐阅读