java 获取DynamoDB分区中的最后一个值

avkwfej4  于 2023-03-11  发布在  Java
关注(0)|答案(1)|浏览(110)

当然,我只想获取按排序键排序的DDB分区中的最后一个值。
缩小后的My Table如下所示:

学生人数|打卡时间|类ID|位置名称

分区键=学生人数
排序键=打孔时间
我正在使用AWS Enhanced Client for java,我得到了这个正在工作的查询,但问题是我受到了限制,(配置的容量不是很高,但仍然不应该只针对这个查询受到限制)。
代码如下所示:

@Override
    public AttendanceTracking findFirstByStudentNrOrderByPunchTimeDesc(String studentNr) {
        DynamoDbTable<AttendanceTracking> attendanceTable = getTable();
        //Only get last db entry sorted by punchTime
        String today = LocalDateTime.now().toString();
        Key fromKey = Key.builder().partitionValue(studentNr).sortValue(today).build();
        QueryConditional queryConditional = QueryConditional
                .sortLessThan(fromKey);
        Iterable<Page<AttendanceTracking>> results =
                attendanceTable.query(QueryEnhancedRequest.builder()
                        .queryConditional(queryConditional)
                        .scanIndexForward(false)
                        .limit(1)
                        .build());
        List<AttendanceTracking> entries = new ArrayList<>();
        results.forEach(page -> entries.addAll(page.items()));
        if (entries.size() > 0) {
            return entries.get(0);
        }
        return null;
    }

另外,执行此查询平均需要6秒?但是在此特定分区中应该只有100个条目。不确定这是否是因为节流以及客户端内置了自动重试功能,我不知道。
我认为这是因为我做了一个sortLess than,但我不能想象它应该扫描分区中的所有值?
请帮帮忙

olhwl3o2

olhwl3o21#

有人在评论中指出了答案。在这种情况下,你不需要SortKey。只需通过Partition键搜索,反向scanIndex限制为1,因为DDB已经对你的数据进行了排序,应该是正确的顺序。它还将查询时间从6秒减少到60毫秒。

@Override
    public AttendanceTracking findFirstByStudentNrOrderByPunchTimeDesc(String studentNr) {
        DynamoDbTable<AttendanceTracking> attendanceTable = getTable();
        //Only get last db entry sorted by punchTime
        String today = LocalDateTime.now().toString();
        QueryConditional queryConditional = QueryConditional
            .keyEqualTo(Key.builder().partitionValue(studentNr).build());
        Iterable<Page<AttendanceTracking>> results =
                attendanceTable.query(QueryEnhancedRequest.builder()
                        .queryConditional(queryConditional)
                        .scanIndexForward(false)
                        .limit(1)
                        .build());
        List<AttendanceTracking> entries = new ArrayList<>();
        results.forEach(page -> entries.addAll(page.items()));
        if (entries.size() > 0) {
            return entries.get(0);
        }
        return null;
    }

相关问题