0

I have a table (users) in Amazon DynamoDB with items like this:

{
   id: "ef1e44bc-03ad-11e9-8eb2-f2801f1b9fd1", // UUID, HASH key
   version: "3.1",                             // Version string, conforming to semver standards
   emailsEnabled: true,                        // Boolean flag
   capabilities: {                             // Big nested object, not important for the question
      …
   }
}

I want to run an ad-hoc scan to tell how many users with version 3.1 have emails enabled. I don't have any indexes here for this table but it's ok to do a scan.

How do I do that with AWS SDK for Java 2.x?

madhead
  • 31,729
  • 16
  • 153
  • 201

1 Answers1

3

You'll have to use Filter Expressions to limit the amount of data processed by your app.

You can also get rid of additional, unimportant, attributes in scan results by using ProjectionExpressions.

Here is the code:

DynamoDbClient client = DynamoDbClient.builder().build();
ScanRequest request =
    ScanRequest
        .builder()
        .tableName("users")
        .filterExpression("version = :version")
        .expressionAttributeValues(
            Map.of(":version", AttributeValue.builder().s("3.1").build()) // Using Java 9+ Map.of
        )
        .projectionExpression("id, version, emailsEnabled")
        .build();
ScanIterable response = client.scanPaginator(request);

for (ScanResponse page : response) {
    for (Map<String, AttributeValue> item : page.items()) {
        // Consume the item
        System.out.println(item);

        if (item.get("emailsEnabled").bool()) {
            // Update counters
        }
    }
}

Note that a filter expression is applied after a scan finishes, but before the results are returned. Therefore, a scan will consume the same amount of read capacity, regardless of whether a filter expression is present or not.

madhead
  • 31,729
  • 16
  • 153
  • 201