Написание DynamoDB «ИЛИ » запрос условия?

#amazon-dynamodb

#amazon-dynamodb

Вопрос:

Я хочу запросить таблицу dynamodb с логическим значением или условием, таким как SQL, например Get me all the items where attribute1 = "no" or attribute2="no"

Я пробовал, scanRequest.withScanFilter но все условия выполняются путем выполнения логических операций. Как мне выполнить логическое преобразование.?

Ответ №1:

Вы можете установить ConditionalOperator для вашего ScanRequest на «ИЛИ». Значение по умолчанию равно «И»

http://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Scan.html

 ScanRequest scanRequest = new ScanRequest("tableName");
scanRequest.setConditionalOperator(ConditionalOperator.OR);

Map<String, Condition> scanFilter = new HashMap<String, Condition>();
scanFilter.put("attribute1", new Condition().withAttributeValueList(new AttributeValue("no")).withComparisonOperator(ComparisonOperator.EQ));
scanFilter.put("attribute2", new Condition().withAttributeValueList(new AttributeValue("no")).withComparisonOperator(ComparisonOperator.EQ));

scanRequest.setScanFilter(scanFilter);
ScanResult scanResult = dynamo.scan(scanRequest);

for(Map<String, AttributeValue> item : scanResult.getItems()) {
    System.out.println(item);
}
  

Комментарии:

1. Будьте осторожны при использовании сканирований. С вас будет взиматься плата за все отсканированные строки, а не за возвращенные строки. Вам действительно никогда не следует использовать сканирование в рабочей среде, если таблица содержит много данных.

Ответ №2:

Если вам известно HashKey значение, другим вариантом может быть использование QUERY и FilterExpression . Вот пример с Java SDK:

 Table table = dynamoDB.getTable(tableName);

Map<String, Object> expressionAttributeValues = new HashMap<String, Object>();
expressionAttributeValues.put(":x", "no");
expressionAttributeValues.put(":y", "no");

QuerySpec spec = new QuerySpec()
    .withHashKey("HashKeyAttributeName", "HashKeyValueHere")
    .withFilterExpression("attribute1 = :x  or attribute2 = :y")
    .withValueMap(expressionAttributeValues);


ItemCollection<QueryOutcome> items = table.query(spec);

Iterator<Item> iterator = items.iterator();

while (iterator.hasNext()) {
    System.out.println(iterator.next().toJSONPretty());
}
  

Для получения более подробной информации см. раздел Задание условий с помощью выражений условий.

Комментарии:

1. Обратите внимание, что выражения фильтра работают с результатами запроса, и с вас взимается плата за размер запроса. Итак, если у вас есть большой объем данных, связанных с каждым хэш-ключом, вы будете платить через нос каждый раз, когда вы запускаете выражение фильтра.

Ответ №3:

Вы также можете использовать скобки в FilterExpression:

 const params = {
  TableName: process.env.PROJECTS_TABLE,
  IndexName: 'teamId-createdAt-index',
  KeyConditionExpression: 'teamId = :teamId',
  ExpressionAttributeValues: {
    ':teamId': verifiedJwt.teamId,
    ':userId': verifiedJwt.userId,
    ':provider': verifiedJwt.provider
  },
  FilterExpression: 'attribute_exists(isNotDeleted) and ((attribute_not_exists(isPrivate)) or (attribute_exists(isPrivate) and userId = :userId and provider = :provider))'
};