#java #amazon-web-services #amazon-dynamodb
#java #amazon-web-services #amazon-dynamodb
Вопрос:
У меня есть таблица DynamoDB. Он имеет хэш-ключ «ID» и ключ диапазона «Category».
Я пытаюсь найти все записи для «Категории», например, comedy.
Это мой класс сопоставления:
@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);
Я просматривал руководство, но не могу его понять, я бы подумал, что это будет простой запрос, который выполняется постоянно, поэтому, возможно, я что-то упускаю:
Заранее спасибо за вашу помощь
Ответ №1:
Notionquest был прав в своем ответе, что я не мог запросить все значения хэш-ключа в заданном состоянии диапазона. Я решил это, создав глобальный вторичный индекс для моего атрибута Category.
Это мой класс mapper:
@ 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;
}
}
Обратите внимание на аннотацию к category для этого.
И тогда мой запрос выглядит так:
VideoDynamoMappingAdapter videosToFind = new VideoDynamoMappingAdapter();
videosToFind.setVideoCategory("Other");
DynamoDBQueryExpression<VideoDynamoMappingAdapter> queryExpression = new DynamoDBQueryExpression<VideoDynamoMappingAdapter>()
.withIndexName("CategoryIndex")
.withHashKeyValues(videosToFind)
.withConsistentRead(false);
List<VideoDynamoMappingAdapter> itemList = mapper.query(VideoDynamoMappingAdapter.class, queryExpression);
System.out.println("test" itemList.size());
Я надеюсь, что это кому-то поможет.
Ответ №2:
Таблица DynamoDB не может быть запрошена только с помощью ключа диапазона без ключа хэша. Однако его можно запросить только с помощью хэш-ключа без ключа диапазона.
Когда таблица DynamoDB запрашивается только по ключу диапазона без ключа хэша, она выдает ValidationException
ошибку .
Unable to read item. Error JSON: {
"message": "Query condition missed key schema element",
"code": "ValidationException"
}
Альтернативным вариантом может быть сканирование базы данных с использованием ключа диапазона. Пожалуйста, обратите внимание, что сканирование DynamoDB является дорогостоящей операцией, поскольку она будет сканировать всю таблицу.
Сканирование таблицы видео по категориям:-
Пожалуйста, обратите внимание, что условие «ИЛИ» используется как «В» поддерживается только для определенных типов данных.
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. Спасибо за ваш ответ. Можете ли вы показать мне, как запрашивать все хэши в диапазоне?
2. Добавлен код сканирования. Как упоминалось в моем предыдущем ответе, запрос невозможен без хэш-ключа.
3. Большое вам спасибо за ответ. Это показало мне, что мое понимание было неверным для документации. Я не думаю, что сканирование каждый раз является хорошим вариантом, поэтому я изменил его, чтобы добавить глобальный вторичный индекс, и я запрашиваю об этом.
4. Могу ли я попросить вас принять ответ как gsi, так и this? На данный момент ни одно из них не принято.
5. Я не могу принять два ответа. Поскольку вопрос в том, как я могу запросить. Я приму мое. Я поддержал ваш. Еще раз спасибо за вашу помощь.