按小于给定日期的日期过滤 DynamoDB 查询

问题描述 投票:0回答:1

我正在使用 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。

谢谢!

java amazon-web-services filter amazon-dynamodb
1个回答
0
投票

您的索引当前只有

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

© www.soinside.com 2019 - 2024. All rights reserved.