Java:使用Mapper查询Range键的所有值的DynamoDB表

时间:2016-10-05 13:56:21

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

我有一张DynamoDb表。它的散列键为“ID”,范围键为“Category”。

我正在尝试查找“类别”的所有条目,例如喜剧。

这是我的映射类:

@DynamoDBTable(tableName = "Videos")
public class VideoDynamoMappingAdapter {

    private String videoID;
    private String videoCategory;
    private String videoArtist;
    private String videoTitle;

    @DynamoDBHashKey(attributeName = "ID")
    public String getVideoID() {
        return videoID;
    }

    public void setVideoID(String videoID) {
        this.videoID = videoID;
    }
    @DynamoDBRangeKey(attributeName = "Category")
    public String getVideoCategory() {
        return videoCategory;
    }

    public void setVideoCategory(String videoCategory) {
        this.videoCategory = videoCategory;
    }

    @DynamoDBAttribute(attributeName = "ArtistName")
    public String getVideoArtist() {
        return videoArtist;
    }

    public void setVideoArtist(String videoArtist) {
        this.videoArtist = videoArtist;
    }

    @DynamoDBAttribute(attributeName = "VideoTitle")
    public String getVideoTitle() {
        return videoTitle;
    }

    public void setVideoTitle(String videoTitle) {
        this.videoTitle = videoTitle;
    }

}

我一直在尝试查询这样的内容:

    DynamoDBQueryExpression<VideoDynamoMappingAdapter> queryExpression = new DynamoDBQueryExpression<VideoDynamoMappingAdapter>()
            .withRangeKeyCondition()


    List<VideoDynamoMappingAdapter> itemList = mapper.query(VideoDynamoMappingAdapter.class, queryExpression);

我一直在查看指南,但我无法理解,我会认为这将是一个简单的查询,一直在做,所以也许我错过了一些东西:

http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/QueryingJavaDocumentAPI.html#DocumentAPIJavaQueryExample

提前感谢您的帮助

2 个答案:

答案 0 :(得分:2)

如果没有Hash密钥,则单独使用Range键无法查询DynamoDB表。但是,如果没有Range键,可以单独使用Hash键查询。

如果单独使用Range键查询DynamoDB表而没有使用Hash键,则会抛出ValidationException

Unable to read item. Error JSON: {
  "message": "Query condition missed key schema element",
  "code": "ValidationException"
}

备用选项是使用Range键扫描数据库。请注意,DynamoDB扫描是一项代价高昂的操作,因为它会扫描整个表格。

按类别扫描视频表: -

请注意“OR”条件用作“IN”仅支持某些数据类型。

public List<VideoDynamoMappingAdapter> getVidoesByCategory(String[] categories) {

        ScanResultPage<VideoDynamoMappingAdapter> videoResultPage = null;
        List<VideoDynamoMappingAdapter> videoList = new ArrayList<>();

        try {

            do {
                DynamoDBMapper dynamoDBMapper = new DynamoDBMapper(dynamoDBClient);

                Map<String, AttributeValue> expressionAttributeValues = new LinkedHashMap<String, AttributeValue>();

                StringBuilder filterExpression = new StringBuilder(); 
                int i = 1;

                for (String category : categories) {
                    if (i==1) {
                        filterExpression.append("Category = " + ":videoCategory" + i);  
                    } else {
                        filterExpression.append(" OR Category = " + ":videoCategory" + i);
                    }

                    expressionAttributeValues.put(":videoCategory" + i, new AttributeValue().withS(category));
                    i++;
                }

                System.out.println("Filterexpression =====>" + filterExpression.toString());

                DynamoDBScanExpression scanExpression = new DynamoDBScanExpression()                
                        .withFilterExpression(filterExpression.toString())
                        .withExpressionAttributeValues(expressionAttributeValues);

                if (videoResultPage != null) {
                    scanExpression.setExclusiveStartKey(videoResultPage.getLastEvaluatedKey());
                }

                videoResultPage = dynamoDBMapper.scanPage(VideoDynamoMappingAdapter.class, scanExpression);

                System.out.println("Results ==========>" + videoResultPage.getResults());

                videoList.addAll(videoResultPage.getResults());

            } while (videoResultPage.getLastEvaluatedKey() != null);

        } catch (Exception db) {

            db.printStackTrace();

        }

        System.out.println(videoList.toString());
        return videoList;

    }

答案 1 :(得分:1)

Notionquest在他的回答中是正确的,我无法在给定的范围条件中查询散列键的所有值。我通过在Category属性上创建全局二级索引来解决这个问题。

这是我的mapper类:

abs

注意该类别的注释。

然后我的查询是这样的:

@ DynamoDBTable(tableName = "AlarmTable")
public class VideoDynamoMappingAdapter {

    private String videoID;
    private String videoCategory;
    private String videoArtist;
    private String videoTitle;

    @DynamoDBHashKey(attributeName = "ID")
    public String getVideoID() {
        return videoID;
    }

    public void setVideoID(String videoID) {
        this.videoID = videoID;
    }

    @DynamoDBIndexHashKey( globalSecondaryIndexName = "CategoryIndex", attributeName = "Category")
    public String getVideoCategory() {
        return videoCategory;
    }

    public void setVideoCategory(String videoCategory) {
        this.videoCategory = videoCategory;
    }

    @DynamoDBAttribute(attributeName = "VideoArtist")
    public String getVideoArtist() {
        return videoArtist;
    }

    public void setVideoArtist(String videoArtist) {
        this.videoArtist = videoArtist;
    }

    @DynamoDBAttribute(attributeName = "VideoTitle")
    public String getVideoTitle() {
        return videoTitle;
    }

    public void setVideoTitle(String videoTitle) {
        this.videoTitle = videoTitle;
    }

}

我希望它有所帮助。