如何编写 DynamoDB 的 “OR” 条件查询?

21

我想使用布尔或条件查询dynamodb表,就像SQL一样。 例如:获取所有属性1 =“no”或属性2 =“no”的项目

我尝试过使用scanRequest.withScanFilter,但所有条件都是通过进行布尔AND操作执行的。 我该如何执行布尔OR操作?

3个回答

9
您可以将ScanRequest的ConditionalOperator设置为“OR”。默认值为“AND”。 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);
}

19
在使用扫描时要小心,你将被收取所有被扫描的行,而不是返回的行。如果表中包含大量数据,建议在生产环境中根本不要使用扫描。 - Aneil Mallavarapu
“ScanRequest”不包含“setConditionalOperator”的定义。 - Kok How Teh

5

在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))'
};

5
如果您知道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());
}

请参阅使用条件表达式指定条件获取更多详细信息。


2
请注意,过滤表达式是在查询结果上操作的,并且您将根据查询大小收费。因此,如果每个哈希键关联的数据量很大,则每次运行过滤表达式时都会付出高昂的代价。 - Aneil Mallavarapu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接