我有一张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);
我一直在查看指南,但我无法理解,我会认为这将是一个简单的查询,一直在做,所以也许我错过了一些东西:
提前感谢您的帮助
答案 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;
}
}
我希望它有所帮助。