Статьи

Запрос элементов DynamoDB с помощью Java, часть 2

В предыдущем посте у нас была возможность выполнить некоторые базовые действия с запросами DynamoDB.

Однако помимо основных действий API DynamoDB предоставляет нам некоторые дополнительные функциональные возможности.

Проекции — это функция, имеющая функцию выбора.
Вы выбираете, какие атрибуты из элемента DynamoDB должны быть выбраны. Помните, что использование проекции не повлияет на выставление счетов.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public Map<String,AttributeValue> getRegisterDate(String email) {
 
        Map<String,String> expressionAttributesNames = new HashMap<>();
        expressionAttributesNames.put("#email","email");
 
        Map<String,AttributeValue> expressionAttributeValues = new HashMap<>();
        expressionAttributeValues.put(":emailValue",new AttributeValue().withS(email));
 
        QueryRequest queryRequest = new QueryRequest()
                .withTableName(TABLE_NAME)
                .withKeyConditionExpression("#email = :emailValue")
                .withExpressionAttributeNames(expressionAttributesNames)
                .withExpressionAttributeValues(expressionAttributeValues)
                .withProjectionExpression("registerDate");
 
        QueryResult queryResult = amazonDynamoDB.query(queryRequest);
 
        List<Map<String,AttributeValue>> attributeValues = queryResult.getItems();
 
        if(attributeValues.size()>0) {
            return attributeValues.get(0);
        } else {
            return null;
        }
    }

Помимо выбора атрибутов мы также можем указать порядок в соответствии с нашим ключом диапазона. Мы запросим таблицу логинов в порядке убывания, используя scanIndexForward.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public List<Map<String,AttributeValue>> fetchLoginsDesc(String email) {
 
        List<Map<String,AttributeValue>> items = new ArrayList<>();
 
        Map<String,String> expressionAttributesNames = new HashMap<>();
        expressionAttributesNames.put("#email","email");
 
        Map<String,AttributeValue> expressionAttributeValues = new HashMap<>();
        expressionAttributeValues.put(":emailValue",new AttributeValue().withS(email));
 
        QueryRequest queryRequest = new QueryRequest()
                .withTableName(TABLE_NAME)
                .withKeyConditionExpression("#email = :emailValue")
                .withExpressionAttributeNames(expressionAttributesNames)
                .withExpressionAttributeValues(expressionAttributeValues)
                .withScanIndexForward(false);
 
        Map<String,AttributeValue> lastKey = null;
 
        do {
 
            QueryResult queryResult = amazonDynamoDB.query(queryRequest);
            List<Map<String,AttributeValue>> results = queryResult.getItems();
            items.addAll(results);
            lastKey = queryResult.getLastEvaluatedKey();
        } while (lastKey!=null);
 
        return items;
    }

Обычной функциональностью баз данных является подсчет элементов, сохраненных в коллекции. В нашем случае мы хотим подсчитать количество входов в систему определенного пользователя. Однако обратите особое внимание, так как функция подсчета делает не более чем подсчет общего количества выбранных элементов, поэтому это будет стоить вам так, как если бы вы выбрали элементы.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
public Integer countLogins(String email) {
        List<Map<String,AttributeValue>> items = new ArrayList<>();
 
        Map<String,String> expressionAttributesNames = new HashMap<>();
        expressionAttributesNames.put("#email","email");
 
        Map<String,AttributeValue> expressionAttributeValues = new HashMap<>();
        expressionAttributeValues.put(":emailValue",new AttributeValue().withS(email));
 
        QueryRequest queryRequest = new QueryRequest()
                .withTableName(TABLE_NAME)
                .withKeyConditionExpression("#email = :emailValue")
                .withExpressionAttributeNames(expressionAttributesNames)
                .withExpressionAttributeValues(expressionAttributeValues)
                .withSelect(Select.COUNT);
 
        Map<String,AttributeValue> lastKey = null;
        QueryResult queryResult = amazonDynamoDB.query(queryRequest);
        List<Map<String,AttributeValue>> results = queryResult.getItems();
        return queryResult.getCount();
    }

Еще одна особенность DynamoDB — получение элементов партиями, даже если они принадлежат разным таблицам. Это действительно полезно в тех случаях, когда данные, относящиеся к определенному контексту, распространяются через разные таблицы. Каждый элемент get обрабатывается и оплачивается как действие чтения DynamoDB. В случае пакетного получения элемента все ключи таблицы должны быть указаны, поскольку целью каждого запроса в BatchGetItem является получение одного элемента.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public Map<String,List<Map<String,AttributeValue>>> getMultipleInformation(String email,String name) {
 
        Map<String,KeysAndAttributes> requestItems = new HashMap<>();
 
        List<Map<String,AttributeValue>> userKeys = new ArrayList<>();
        Map<String,AttributeValue> userAttributes = new HashMap<>();
        userAttributes.put("email",new AttributeValue().withS(email));
        userKeys.add(userAttributes);
        requestItems.put(UserRepository.TABLE_NAME,new KeysAndAttributes().withKeys(userKeys));
 
        List<Map<String,AttributeValue>> supervisorKeys = new ArrayList<>();
        Map<String,AttributeValue> supervisorAttributes = new HashMap<>();
        supervisorAttributes.put("name",new AttributeValue().withS(name));
        supervisorKeys.add(supervisorAttributes);
        requestItems.put(SupervisorRepository.TABLE_NAME,new KeysAndAttributes().withKeys(supervisorKeys));
 
        BatchGetItemRequest batchGetItemRequest = new BatchGetItemRequest();
        batchGetItemRequest.setRequestItems(requestItems);
 
        BatchGetItemResult batchGetItemResult = amazonDynamoDB.batchGetItem(batchGetItemRequest);
 
        Map<String,List<Map<String,AttributeValue>>> responses = batchGetItemResult.getResponses();
 
        return responses;
    }

Вы можете найти исходный код на GitHub