DynamoDB에서 Query 또는 Scan API를 사용하여 결과를 주문할 수 있습니까?
DynamoDB에 SQL 쿼리의 [ORDER BY 'field']와 같은 것이 있는지 알고 싶습니다.
감사.
답변:
그러나 명시 적으로는 아니지만 많은 실제 사용 사례에서 순서가 분명히 필요하며 그에 따라 해시 및 범위 유형 기본 키 를 사용하여 모델링 할 수 있습니다 .
이 경우 기본 키는 두 가지 속성으로 구성됩니다. 첫 번째 속성은 해시 속성이고 두 번째 속성은 범위 속성입니다. Amazon DynamoDB는 해시 기본 키 속성에 정렬되지 않은 해시 인덱스를 만들고 범위 기본 키 속성에 정렬 된 범위 인덱스를 만듭니다. [내 강조]
그런 다음을 통해 선택적으로 요청 항목이 범위 인덱스를 사용할 수 있습니다 RangeKeyCondition의 의 매개 변수 쿼리 API 및 지정 앞이나 인덱스의 뒤로 통과 비아 (즉, 정렬 방향) ScanIndexForward 매개 변수입니다.
업데이트 : 동일한 방식으로 local secondary index 가있는 속성별로 주문할 수 있습니다 .
정렬 키를 사용하고 쿼리 에 ScanIndexForward 매개 변수를 적용하여 오름차순 또는 내림차순으로 정렬 할 수 있습니다. 여기서는 반환되는 항목을 1 개로 제한합니다.
var params = {
TableName: 'Events',
KeyConditionExpression: 'Organizer = :organizer',
Limit: 1,
ScanIndexForward: false, // true = ascending, false = descending
ExpressionAttributeValues: {
':organizer': organizer
}
};
docClient.query(params, function(err, data) {
if (err) {
console.log(JSON.stringify(err, null, 2));
} else {
console.log(JSON.stringify(data, null, 2));
}
});
ScanIndexForward (오름차순은 true, 내림차순은 false)를 사용하고 쿼리 표현식의 setLimit 값을 사용하여 결과를 제한 할 수도 있습니다.
단일 레코드를 찾기 위해 QueryPage를 사용한 코드 아래에서 찾으십시오.
public void fetchLatestEvents() {
EventLogEntitySave entity = new EventLogEntitySave();
entity.setId("1C6RR7JM0JS100037_contentManagementActionComplete");
DynamoDBQueryExpression<EventLogEntitySave> queryExpression = new DynamoDBQueryExpression<EventLogEntitySave>().withHashKeyValues(entity);
queryExpression.setScanIndexForward(false);
queryExpression.withLimit(1);
queryExpression.setLimit(1);
List<EventLogEntitySave> result = dynamoDBMapper.queryPage(EventLogEntitySave.class, queryExpression).getResults();
System.out.println("size of records = "+result.size() );
}
@DynamoDBTable(tableName = "PROD_EA_Test")
public class EventLogEntitySave {
@DynamoDBHashKey
private String id;
private String reconciliationProcessId;
private String vin;
private String source;
}
public class DynamoDBConfig {
@Bean
public AmazonDynamoDB amazonDynamoDB() {
String accesskey = "";
String secretkey = "";
//
// creating dynamo client
BasicAWSCredentials credentials = new BasicAWSCredentials(accesskey, secretkey);
AmazonDynamoDB dynamo = new AmazonDynamoDBClient(credentials);
dynamo.setRegion(Region.getRegion(Regions.US_WEST_2));
return dynamo;
}
@Bean
public DynamoDBMapper dynamoDBMapper() {
return new DynamoDBMapper(amazonDynamoDB());
}
}
문제를 해결해야하는 또 다른 옵션은
이렇게하면 필요에 따라 테이블 값을 정렬 할 수 있습니다. 전체 쿼리를 가져온 다음 나중에 필터링 할 필요없이 테이블에서 가장 높은 순위의 항목을 찾는 매우 효율적인 방법입니다.
boto2 를 사용 하고 있고 테이블의 열 중 하나에 정렬 키가있는 경우 다음과 같이 말하여 검색 한 내용을 순서대로 또는 역순으로 정렬 할 수 있습니다.
result = users.query_2(
account_type__eq='standard_user',
reverse=True)
boto3 를 사용 하고 있고 결과를 정렬하려는 열에 정렬 키가있는 경우 다음과 같이 말하여 검색 한 데이터를 정렬 할 수 있습니다.
result = users.query(
KeyConditionExpression=Key('account_type').eq('standard_user'),
ScanIndexForward=True)
경우 boto3에 기억 ScanIndexForward는 사실, DynamoDB의 그들이 (정렬 키 값에 의해) 저장되는 순서대로 결과를 반환합니다. 이것이 기본 동작입니다. ScanIndexForward가 false이면 DynamoDB는 정렬 키 값에 따라 역순으로 결과를 읽은 다음 결과를 클라이언트에 반환합니다.
그런 사소한 작업이 DynamoDB에서 문제가 될 수 있다고는 생각하지 못했습니다. Dynamo에는 몇 가지 기본 파티션이 필요합니다. 추가 열 상태를 추가하여 데이터를 주문했습니다. 다음 두 필드를 사용하여 GSI 인덱스를 생성했습니다. createdAt 필드에서 status = "active"인 데이터를 주문합니다.
GSI 생성
{
IndexName: "createdAt",
KeySchema: [
{ AttributeName: "status", KeyType: "HASH" },
{ AttributeName: "createdAt", KeyType: "RANGE" }
],
Projection: { ProjectionType: "ALL" },
ProvisionedThroughput: {
ReadCapacityUnits: N,
WriteCapacityUnits: N
}
}
쿼리 데이터
const result = await this.dynamoClient.query({
TableName: "my table",
IndexName: "createdAt",
KeyConditionExpression: "#status = :status and #createdAt > :createdAt",
Limit: 5,
ExpressionAttributeValues: {
":status": {
"S": "active"
},
":createdAt": {
"S": "2020-12-10T15:00:00.000Z"
}
},
ExpressionAttributeNames: {
"#status": "status",
"#createdAt": "createdAt"
},
});