我希望在应用一些过滤器后,根据存储为ISO-8601格式uuuu-MM-dd
的日期字段对前10或20等基本上可配置的数字进行排序。
@DynamoDBTable(tableName = "Data")
@NoArgsConstructor
@ToString
public class Data {
private LocalDate date;
@Setter
private Long number;
@Setter
private STATUS status;
@DynamoDBHashKey
@DynamoDBTypeConverted(converter = LocalDateConverter.class)
public LocalDate getDate() {
return date;
}
@DynamoDBTypeConverted(converter = LocalDateConverter.class)
public void setDate(LocalDate date) {
this.date = date;
}
@DynamoDBIndexHashKey(globalSecondaryIndexName = "idx_Data_number")
public Long getCompetitionId() {
return number;
}
@DynamoDBTypeConvertedEnum
@DynamoDBIndexHashKey(globalSecondaryIndexName = "idx_Data_status")
public STATUS getStatus() {
return status;
}
}
我需要根据数字和多个状态过滤后根据日期字段排序的20条记录。我使用ScanRequest
基本上过滤了记录。现在我想限制结果并根据日期获得最佳记录。
@AllArgsConstructor
public class DataRepositoryImpl implements DataRepository {
private final DynamoDBMapper dynamoDBMapper;
private final AmazonDynamoDB amazonDynamoDB;
@Override
public List<Data> findAll(Long number, List<String> status) {
Condition numberCondition = new Condition()
.withComparisonOperator(ComparisonOperator.EQ)
.withAttributeValueList(new AttributeValue().withN(String.valueOf(number)));
List<AttributeValue> attributeValues = newArrayList();
status.forEach(s -> attributeValues.add(new AttributeValue().withS(s)));
Condition statusCondition = new Condition()
.withComparisonOperator(ComparisonOperator.IN)
.withAttributeValueList(attributeValues);
Map<String, Condition> conditions = newHashMap();
conditions.put("number", numberCondition);
conditions.put("status", statusCondition);
ScanRequest scanRequest = new ScanRequest()
.withTableName("Data")
.withScanFilter(conditions)
.withConditionalOperator(ConditionalOperator.AND);
ScanResult scanResult = amazonDynamoDB.scan(scanRequest);
return dynamoDBMapper.marshallIntoObjects(Data.class, scanResult.getItems());
}
}
答案 0 :(得分:2)
DynamoDB仅按 SORT KEY 属性对数据进行排序。
DynamoDB没有按照sort key
除外的任何属性(即任何非键属性或分区键属性)对数据进行排序的功能。
分区键和排序键 - 称为复合主键, 这种类型的密钥由两个属性组成。第一个属性是 分区键,第二个属性是排序键。 DynamoDB 使用分区键值作为内部哈希函数的输入。 散列函数的输出确定分区(物理 存储项目的DynamoDB内部存储。所有 具有相同分区键的项目按排序顺序存储在一起 按排序键值。
DynamoDB将数据存储在多个分区中。与RDBMS一样,它也没有任何ORDER BY
子句。但是,它具有ScanIndexForward
选项,只能应用于Sort
键属性。
ScanIndexForward - (布尔值)指定索引遍历的顺序: 如果为true(默认),则以递增顺序执行遍历;如果 false,遍历按降序执行。
答案 1 :(得分:1)
我不相信您可以使用DynamoDB实现这一目标。您必须使用应用程序代码订购和过滤结果。
如果您使用排序键,DynamoDB返回有序结果的唯一方法。但是,您的初始查询是多维的(一个数字,多个状态&#39;),因此您无法创建在这种情况下可用的分区。
如果您想查询单个号码,并按日期排序,则可以使用数字作为分区键,使用新的日期作为长号码&#39;属性作为排序键。 DynamoDB密钥只能是String,Number or Binary attributes。我假设您的LocalDateConverter将日期更改为字符串,因此这不会成为一个好的排序键。但是,您可以添加一个新的属性,该属性是一个数字,并以YYYYMMDDHHMMSS格式表示日期,这自然会按正确的顺序排序。然后,您可以使用DynamoDB ScanIndexForward函数并将结果集限制为给定数量的项目。
答案 2 :(得分:0)
您可以在扫描中设置Limit
。 ScanRequest#setLimit
要评估的最大项目数(不一定是 匹配项目)。如果DynamoDB处理的项目数量最多 在处理结果时限制,它会停止操作并返回 截至该点的匹配值,以及LastEvaluatedKey中的键 适用于后续操作,以便您可以在哪里接听 离开了。
但我怀疑dynamodb会对scan
中的任何键进行排序。
您可以创建本地索引,这将帮助您检索限制和排序。