我正在使用 DynamoDB 做一个 java springboot 项目。我有这个问题:
我有一个 dynamoDB 表,其构造如下:
aws dynamodb create-table \
--table-name my-table \
--attribute-definitions \
AttributeName=my_id,AttributeType=S \
AttributeName=my_type,AttributeType=S \
AttributeName=creation_date,AttributeType=N \
--key-schema \
AttributeName=my_id,KeyType=HASH \
AttributeName=my_type,KeyType=RANGE \
--billing-mode PAY_PER_REQUEST \
--endpoint-url $ENDPOINT:$PORT \
--global-secondary-indexes \
"[
{
\"IndexName\": \"CreationDateIndex\",
\"KeySchema\": [{\"AttributeName\":\"creation_date\",\"KeyType\":\"HASH\"}],
\"Projection\":{
\"ProjectionType\":\"ALL\"
},
\"ProvisionedThroughput\": {
\"ReadCapacityUnits\": 10,
\"WriteCapacityUnits\": 5
}
}
]"
这是实体:
@NotNull
@DynamoDBHashKey(attributeName = "my_id")
protected UUID myId;
@NotNull
@DynamoDBRangeKey(attributeName = "my_type")
protected String myType;
@DynamoDBIndexHashKey(globalSecondaryIndexName = "CreationDateIndex")
@DynamoDBAttribute(attributeName = "creation_date")
protected long creationDate;
我想在存储库中创建一个方法,删除creation_date小于给定日期的所有行(实际上我将epochSeconds保存为creation_date),但是如果我构建查询,我没有添加比较选项
.withComparisonOperator(ComparisonOperator.LE)
.
如何创建查询?
我找到的唯一解决方案是使用 DynamoDBScanExpression,但这效率不高。这是当前的解决方案:
@Override
public boolean delete(long creationDateBefore) throws InterruptedException {
System.out.println("STARTING DELETING objects");
List<MyEntity> objectsToDelete = findByCreationDateBefore(creationDateBefore);
System.out.println("DELETING " + objectsToDelete.size() + " objects");
return batchDelete(objectsToDelete).isEmpty();
}
private List<MyEntity> findByCreationDateBefore(long creationDateBefore) {
DynamoDBScanExpression scanExpression = new DynamoDBScanExpression();
scanExpression.addFilterCondition(
"creation_date",
new Condition()
.withComparisonOperator(ComparisonOperator.LE)
.withAttributeValueList(new AttributeValue().withN(String.valueOf(creationDateBefore)))
);
return dbMapper.scan(MyEntity.class, scanExpression);
}
您还有其他可能的解决方案吗? 我可以修改表,但索引必须始终是哈希 my_id + 范围 my_type。
谢谢!
您的索引当前只有
creation_date
,它只允许您指定确切的日期,因为您在查询时必须始终知道整个分区键。
为了克服这个问题,您可以为您的项目添加静态值,我们称之为
GSI1_PK
:
GSI_PK | 创建日期 | 数据 |
---|---|---|
1 | 2023-12-16T00:00:000 | 一些数据 |
1 | 2023-12-16T01:00:000 | 一些数据 |
1 | 2023-12-16T02:00:000 | 一些数据 |
1 | 2023-12-16T03:00:000 | 一些数据 |
1 | 2023-12-16T03:00:000 | 一些数据 |
1 | 2023-12-16T04:00:000 | 一些数据 |
现在您可以发出
Query
其中 GSI_PK = 1 AND creation_date < $DATE