web/Spring

dynamoDbEnhancedClient에서 QueryConditional에서 sort key range 조회하기

반응형

아래와 같이 데이터가 존재하는 상황을 가정해보자.

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가 사용성이 좋아졌다고 해도 쓰기 어렵다;; 

반응형