반응형
아래와 같이 데이터가 존재하는 상황을 가정해보자.
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbBean;
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbPartitionKey;
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbSortKey;
@Getter
@Setter
@DynamoDbBean
@NoArgsConstructor
public class Log {
private String key;
private String requestDateTime;
private String response;
@Builder
public Log(String key, String requestDateTime, String response) {
this.key = key;
this.requestDateTime = requestDateTime;
this.response = response;
}
@DynamoDbPartitionKey
public String getKey() {
return this.key;
}
@DynamoDbSortKey
public String getRequestDateTime() {
return this.requestDateTime;
}
}
이 상황에서 같은 key의 값 중 requestDateTime의 값이 특정 구간의 날짜에 데이터를 가져오려고 한다면 어떻게 해아할까? 처음에는 filterExpression을 제공하기 때문에 아래와 같이 조회를 시도했었다.
public class LogFinder {
public static final String TABLE_NAME = "log";
private final DynamoDbTable<Log> dynamoDbTable;
public LogFinder(DynamoDbEnhancedClient dynamoDbEnhancedClient) {
this.dynamoDbTable = dynamoDbEnhancedClient.table(TABLE_NAME, TableSchema.fromBean(Log.class));
}
public List<Log> findQuery(LogQuery query) {
QueryEnhancedRequest queryEnhancedRequest = QueryEnhancedRequest.builder()
.queryConditional(query.getQueryConditional())
.filterExpression(query.getFilterExpression())
.limit(query.getLimit())
.scanIndexForward(false)
.build();
return dynamoDbTable.query(queryEnhancedRequest).stream().flatMap(d -> d.items().stream()).collect(Collectors.toList());
}
}
public class LogQuery {
public QueryConditional getQueryConditional() {
return QueryConditional.keyEqualTo(Key.builder()
.partitionValue(key())
.build());
}
public Expression getFilterExpression() {
Map<String, AttributeValue> expressionValue = new HashMap<>();
expressionValue.put(":startDateTime", AttributeValue.builder()
.s(startDateTime)
.build());
expressionValue.put(":endDateTime", AttributeValue.builder()
.s(endDateTime)
.build());
return Expression.builder()
.expression("requestDateTime between :startDateTime and :endDateTime")
.expressionValues(expressionValue)
.build();
}
}
하지만 key값에 filterExpression이 정상적으로 먹지 못했고 QueryConditional의 Key에 대한 조건으로 다음과 같이 명시해줘서 해결했다.
public class LogFinder {
public static final String TABLE_NAME = "log";
private final DynamoDbTable<Log> dynamoDbTable;
public LogFinder(DynamoDbEnhancedClient dynamoDbEnhancedClient) {
this.dynamoDbTable = dynamoDbEnhancedClient.table(TABLE_NAME, TableSchema.fromBean(Log.class));
}
public List<Log> findQuery(LogQuery query) {
QueryEnhancedRequest queryEnhancedRequest = QueryEnhancedRequest.builder()
.queryConditional(query.getQueryConditional())
.limit(query.getLimit())
.scanIndexForward(false)
.build();
return dynamoDbTable.query(queryEnhancedRequest).stream().flatMap(d -> d.items().stream()).collect(Collectors.toList());
}
}
public class LogQuery {
// 변경된 부분
public QueryConditional getQueryConditional() {
Key fromKey = Key.builder().partitionValue(key()).sortValue(startDateTime).build();
Key toKey = Key.builder().partitionValue(key()).sortValue(endDateTime).build();
return QueryConditional
.sortBetween(fromKey, toKey);
}
}
아무리 dynamoDbEnhancedClient가 사용성이 좋아졌다고 해도 쓰기 어렵다;;
반응형
'web > Spring' 카테고리의 다른 글
Mapstruct 사용 시 collection 내부에 이름이 다른경우 (0) | 2023.03.25 |
---|---|
dynamoDbEnhancedClient range query condition 사용 시 The provided starting key does not match the range key predicate 에러 발생 (0) | 2022.11.05 |
Dynamodb enhanced client (0) | 2022.07.24 |
lombok에서 @builder annotation 사용 후 static 접근 시 cannot find symbol 에러 문제 (0) | 2022.06.05 |
Gradle build 시 node js 버전을 지정하여 빌드하기 (3) | 2022.04.23 |