0

Для веб-приложения я хочу реализовать разбитый на страницы таблицы. «Макет» DynamoDB заключается в том, что для пользователя есть несколько элементов, поэтому я выбрал partition key=user и sort key=created (временная метка). Пользовательский интерфейс должен представить элементы на страницах с 50 элементами из всего нескольких элементов.PaginatedList DynamoDB через REST

Элементы передаются в пользовательский интерфейс через вызовы REST-Api. Я хочу только query или scan страницы, а не всю таблицу. Разбиение страницы возможно вперед и назад.

До сих пор я придумал с нижеследующим, используя DynamoDBMapper:

/** 
* Returns the next page of items DEPENDENT OF THE USER. Note: This method internally uses 
* DynamoDB QUERY. Thus it requires "user" as a parameter. The "created" parameter is optional. 
* If provided, both parameters form the startKey for the pagination. 
* 
* @param user - mandatory: The user for which to get the next page 
* @param created - optional: for providing a starting point 
* @param limit - the returned page will contain (up to) this number of items 
* @return 
*/ 
public List<SampleItem> getNextPageForUser(final String user, final Long created, final int limit) { 
    // To iterate DEPENDENT on the user we use QUERY. The DynamoDB QUERY operation 
    // always require the partition key (=user). 
    final SampleItem hashKeyObject = new SampleItem(); 
    hashKeyObject.setUser(user); 

    // The created is optional. If provided, it references the starting point 
    if (created == null) { 
     final DynamoDBQueryExpression<SampleItem> pageExpression = new DynamoDBQueryExpression<SampleItem>()// 
       .withHashKeyValues(hashKeyObject)// 
       .withScanIndexForward(true) // 
       .withLimit(limit); 
     return mapper.queryPage(SampleItem.class, pageExpression).getResults(); 
    } else { 
     final Map<String, AttributeValue> startKey = new HashMap<String, AttributeValue>(); 
     startKey.put(SampleItem.USER, new AttributeValue().withS(user)); 
     startKey.put(SampleItem.CREATED, new AttributeValue().withN(created.toString())); 

     final DynamoDBQueryExpression<SampleItem> pageExpression = new DynamoDBQueryExpression<SampleItem>()// 
       .withHashKeyValues(hashKeyObject)// 
       .withExclusiveStartKey(startKey)// 
       .withScanIndexForward(true) // 
       .withLimit(limit); 
     return mapper.queryPage(SampleItem.class, pageExpression).getResults(); 
    } 
} 

Код для предыдущего похож, только то, что он использует withScanIndexForward(false).

В моем контроллере REST-Api Я предлагаю один метод:

@RequestMapping(value = "/page/{user}/{created}", method = RequestMethod.GET) 
public List<SampleDTO> listQueriesForUserWithPagination(// 
     @RequestParam(required = true) final String user,// 
     @RequestParam(required = true) final Long created,// 
     @RequestParam(required = false) final Integer n,// 
     @RequestParam(required = false) final Boolean isBackward// 
) { 
    final int nrOfItems = n == null ? 100 : n; 
    if (isBackward != null && isBackward.booleanValue()) { 
     return item2dto(myRepo.getPrevQueriesForUser(user, created, nrOfItems)); 
    } else { 
     return item2dto(myRepo.getNextQueriesForUser(user, created, nrOfItems)); 
    } 
} 

Интересно, если я заново изобретать колесо с таким подходом.

Можно ли передать DynamicDB PaginatedQueryList или PaginatedScanList в UI через REST, так что, если javascript разбивает страницы на элементы, то тогда они загружаются лениво. От работы с другими БД я никогда не передавал объекты записи БД, поэтому мой код-фрагмент повторно упаковывает данные (item2dto).

Кроме того, разбиение на страницы с DynamoDB выглядит несколько странно: до сих пор я не видел возможности предоставить пользовательскому интерфейсу общее количество элементов. Таким образом, пользовательский интерфейс имеет только кнопки для «следующей страницы» и «предыдущей страницы», не зная, сколько страниц будет следовать. Поэтому прямое переключение на страницу 5 невозможно.

ответ

0

Консоль AWS не загружает сразу все ваши данные, чтобы сохранить емкость чтения. Когда вы получаете страницу «Сканирование/запрос», вы получаете информацию о том, как получить следующую страницу, поэтому консоль не может показать вам, сколько страниц данных она может показать. В зависимости от вашей схемы вы можете поддерживать случайный доступ к страницам в своем приложении. Это делается путем определения априорного того, как будут стоять большие страницы, и второго кодирования, например, номера страницы в ключе раздела. Пожалуйста, см. this AWS Forum post.