There are more AWS SDK examples available in the AWS Doc SDK Examples
The following code examples show how to perform advanced query operations in DynamoDB.
Query tables using various filtering and condition techniques.
Implement pagination for large result sets.
Use Global Secondary Indexes for alternate access patterns.
Apply consistency controls based on application requirements.
- SDK for Java 2.x
-
Query with strongly consistent reads using AWS SDK for Java 2.x.
import software.amazon.awssdk.services.dynamodb.DynamoDbClient; import software.amazon.awssdk.services.dynamodb.model.AttributeValue; import software.amazon.awssdk.services.dynamodb.model.DynamoDbException; import software.amazon.awssdk.services.dynamodb.model.QueryRequest; import software.amazon.awssdk.services.dynamodb.model.QueryResponse; import software.amazon.awssdk.services.dynamodb.model.ResourceNotFoundException; import java.util.HashMap; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; public QueryResponse queryWithConsistentReads( final String tableName, final String partitionKeyName, final String partitionKeyValue, final boolean useConsistentRead) { CodeSampleUtils.validateTableParameters(tableName, partitionKeyName, partitionKeyValue); // Create expression attribute names for the column names final Map<String, String> expressionAttributeNames = new HashMap<>(); expressionAttributeNames.put(EXPRESSION_ATTRIBUTE_NAME_PK, partitionKeyName); // Create expression attribute values for the column values final Map<String, AttributeValue> expressionAttributeValues = new HashMap<>(); expressionAttributeValues.put( EXPRESSION_ATTRIBUTE_VALUE_PK, AttributeValue.builder().s(partitionKeyValue).build()); // Create the query request final QueryRequest queryRequest = QueryRequest.builder() .tableName(tableName) .keyConditionExpression(KEY_CONDITION_EXPRESSION) .expressionAttributeNames(expressionAttributeNames) .expressionAttributeValues(expressionAttributeValues) .consistentRead(useConsistentRead) .build(); try { final QueryResponse response = dynamoDbClient.query(queryRequest); LOGGER.log(Level.INFO, "Query successful. Found {0} items", response.count()); return response; } catch (ResourceNotFoundException e) { LOGGER.log(Level.SEVERE, "Table not found: {0}", tableName); throw e; } catch (DynamoDbException e) { LOGGER.log(Level.SEVERE, "Error querying with consistent reads", e); throw e; } }
Query using a Global Secondary Index with AWS SDK for Java 2.x.
import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.dynamodb.DynamoDbClient; import software.amazon.awssdk.services.dynamodb.model.AttributeValue; import software.amazon.awssdk.services.dynamodb.model.DynamoDbException; import software.amazon.awssdk.services.dynamodb.model.QueryRequest; import software.amazon.awssdk.services.dynamodb.model.QueryResponse; import software.amazon.awssdk.services.dynamodb.model.ResourceNotFoundException; import java.util.HashMap; import java.util.Map; public QueryResponse queryTable( final String tableName, final String partitionKeyName, final String partitionKeyValue) { CodeSampleUtils.validateTableParameters(tableName, partitionKeyName, partitionKeyValue); // Create expression attribute names for the column names final Map<String, String> expressionAttributeNames = new HashMap<>(); expressionAttributeNames.put(EXPRESSION_ATTRIBUTE_NAME_PK, partitionKeyName); // Create expression attribute values for the column values final Map<String, AttributeValue> expressionAttributeValues = new HashMap<>(); expressionAttributeValues.put( EXPRESSION_ATTRIBUTE_VALUE_PK, AttributeValue.builder().s(partitionKeyValue).build()); // Create the query request final QueryRequest queryRequest = QueryRequest.builder() .tableName(tableName) .keyConditionExpression(KEY_CONDITION_EXPRESSION) .expressionAttributeNames(expressionAttributeNames) .expressionAttributeValues(expressionAttributeValues) .build(); try { final QueryResponse response = dynamoDbClient.query(queryRequest); System.out.println("Query on base table successful. Found " + response.count() + " items"); return response; } catch (ResourceNotFoundException e) { System.err.format("Error: The Amazon DynamoDB table \"%s\" can't be found.\n", tableName); throw new DynamoDbQueryException("Table not found: " + tableName, e); } catch (DynamoDbException e) { System.err.println("Error querying base table: " + e.getMessage()); throw new DynamoDbQueryException("Failed to execute query on base table", e); } } /** * Queries a DynamoDB Global Secondary Index (GSI) by partition key. * * @param tableName The name of the DynamoDB table * @param indexName The name of the GSI * @param partitionKeyName The name of the GSI partition key attribute * @param partitionKeyValue The value of the GSI partition key to query * @return The query response from DynamoDB * @throws ResourceNotFoundException if the table or index doesn't exist * @throws DynamoDbException if the query fails */ public QueryResponse queryGlobalSecondaryIndex( final String tableName, final String indexName, final String partitionKeyName, final String partitionKeyValue) { CodeSampleUtils.validateTableParameters(tableName, partitionKeyName, partitionKeyValue); CodeSampleUtils.validateStringParameter("Index name", indexName); // Create expression attribute names for the column names final Map<String, String> expressionAttributeNames = new HashMap<>(); expressionAttributeNames.put(EXPRESSION_ATTRIBUTE_NAME_IK, partitionKeyName); // Create expression attribute values for the column values final Map<String, AttributeValue> expressionAttributeValues = new HashMap<>(); expressionAttributeValues.put( EXPRESSION_ATTRIBUTE_VALUE_IK, AttributeValue.builder().s(partitionKeyValue).build()); // Create the query request final QueryRequest queryRequest = QueryRequest.builder() .tableName(tableName) .indexName(indexName) .keyConditionExpression(GSI_KEY_CONDITION_EXPRESSION) .expressionAttributeNames(expressionAttributeNames) .expressionAttributeValues(expressionAttributeValues) .build(); try { final QueryResponse response = dynamoDbClient.query(queryRequest); System.out.println("Query on GSI successful. Found " + response.count() + " items"); return response; } catch (ResourceNotFoundException e) { System.err.format( "Error: The Amazon DynamoDB table \"%s\" or index \"%s\" can't be found.\n", tableName, indexName); throw new DynamoDbQueryException("Table or index not found: " + tableName + "/" + indexName, e); } catch (DynamoDbException e) { System.err.println("Error querying GSI: " + e.getMessage()); throw new DynamoDbQueryException("Failed to execute query on GSI", e); } }
Query with pagination using AWS SDK for Java 2.x.
import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.dynamodb.DynamoDbClient; import software.amazon.awssdk.services.dynamodb.model.AttributeValue; import software.amazon.awssdk.services.dynamodb.model.DynamoDbException; import software.amazon.awssdk.services.dynamodb.model.QueryRequest; import software.amazon.awssdk.services.dynamodb.model.QueryResponse; import software.amazon.awssdk.services.dynamodb.model.ResourceNotFoundException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public List<Map<String, AttributeValue>> queryWithPagination( final String tableName, final String partitionKeyName, final String partitionKeyValue, final int pageSize) { CodeSampleUtils.validateTableParameters(tableName, partitionKeyName, partitionKeyValue); CodeSampleUtils.validatePositiveInteger("Page size", pageSize); // Create expression attribute names for the column names final Map<String, String> expressionAttributeNames = new HashMap<>(); expressionAttributeNames.put(EXPRESSION_ATTRIBUTE_NAME_PK, partitionKeyName); // Create expression attribute values for the column values final Map<String, AttributeValue> expressionAttributeValues = new HashMap<>(); expressionAttributeValues.put( EXPRESSION_ATTRIBUTE_VALUE_PK, AttributeValue.builder().s(partitionKeyValue).build()); // Create the query request QueryRequest.Builder queryRequestBuilder = QueryRequest.builder() .tableName(tableName) .keyConditionExpression(KEY_CONDITION_EXPRESSION) .expressionAttributeNames(expressionAttributeNames) .expressionAttributeValues(expressionAttributeValues) .limit(pageSize); // List to store all items from all pages final List<Map<String, AttributeValue>> allItems = new ArrayList<>(); // Map to store the last evaluated key for pagination Map<String, AttributeValue> lastEvaluatedKey = null; int pageNumber = 1; try { do { // If we have a last evaluated key, use it for the next page if (lastEvaluatedKey != null) { queryRequestBuilder.exclusiveStartKey(lastEvaluatedKey); } // Execute the query final QueryResponse response = dynamoDbClient.query(queryRequestBuilder.build()); // Process the current page of results final List<Map<String, AttributeValue>> pageItems = response.items(); allItems.addAll(pageItems); // Get the last evaluated key for the next page lastEvaluatedKey = response.lastEvaluatedKey(); if (lastEvaluatedKey != null && lastEvaluatedKey.isEmpty()) { lastEvaluatedKey = null; } System.out.println("Page " + pageNumber + ": Retrieved " + pageItems.size() + " items (Running total: " + allItems.size() + ")"); pageNumber++; } while (lastEvaluatedKey != null); System.out.println("Query with pagination complete. Retrieved a total of " + allItems.size() + " items across " + (pageNumber - 1) + " pages"); return allItems; } catch (ResourceNotFoundException e) { System.err.format("Error: The Amazon DynamoDB table \"%s\" can't be found.\n", tableName); throw e; } catch (DynamoDbException e) { System.err.println("Error querying with pagination: " + e.getMessage()); throw e; } }
Query with complex filters using AWS SDK for Java 2.x.
import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.dynamodb.DynamoDbClient; import software.amazon.awssdk.services.dynamodb.model.AttributeValue; import software.amazon.awssdk.services.dynamodb.model.DynamoDbException; import software.amazon.awssdk.services.dynamodb.model.QueryRequest; import software.amazon.awssdk.services.dynamodb.model.QueryResponse; import software.amazon.awssdk.services.dynamodb.model.ResourceNotFoundException; import java.util.HashMap; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; public QueryResponse queryWithComplexFilter( final String tableName, final String partitionKeyName, final String partitionKeyValue, final String statusAttrName, final String activeStatus, final String pendingStatus, final String priceAttrName, final double minPrice, final double maxPrice, final String categoryAttrName) { // Validate parameters CodeSampleUtils.validateTableParameters(tableName, partitionKeyName, partitionKeyValue); CodeSampleUtils.validateStringParameter("Status attribute name", statusAttrName); CodeSampleUtils.validateStringParameter("Active status", activeStatus); CodeSampleUtils.validateStringParameter("Pending status", pendingStatus); CodeSampleUtils.validateStringParameter("Price attribute name", priceAttrName); CodeSampleUtils.validateStringParameter("Category attribute name", categoryAttrName); CodeSampleUtils.validateNumericRange("Minimum price", minPrice, 0.0, Double.MAX_VALUE); CodeSampleUtils.validateNumericRange("Maximum price", maxPrice, minPrice, Double.MAX_VALUE); // Create expression attribute names for the column names final Map<String, String> expressionAttributeNames = new HashMap<>(); expressionAttributeNames.put("#pk", partitionKeyName); expressionAttributeNames.put(EXPRESSION_ATTRIBUTE_NAME_STATUS, statusAttrName); expressionAttributeNames.put(EXPRESSION_ATTRIBUTE_NAME_PRICE, priceAttrName); expressionAttributeNames.put(EXPRESSION_ATTRIBUTE_NAME_CATEGORY, categoryAttrName); // Create expression attribute values for the column values final Map<String, AttributeValue> expressionAttributeValues = new HashMap<>(); expressionAttributeValues.put( ":pkValue", AttributeValue.builder().s(partitionKeyValue).build()); expressionAttributeValues.put( EXPRESSION_ATTRIBUTE_VALUE_ACTIVE, AttributeValue.builder().s(activeStatus).build()); expressionAttributeValues.put( EXPRESSION_ATTRIBUTE_VALUE_PENDING, AttributeValue.builder().s(pendingStatus).build()); expressionAttributeValues.put( EXPRESSION_ATTRIBUTE_VALUE_MIN_PRICE, AttributeValue.builder().n(String.valueOf(minPrice)).build()); expressionAttributeValues.put( EXPRESSION_ATTRIBUTE_VALUE_MAX_PRICE, AttributeValue.builder().n(String.valueOf(maxPrice)).build()); // Create the query request final QueryRequest queryRequest = QueryRequest.builder() .tableName(tableName) .keyConditionExpression(KEY_CONDITION_EXPRESSION) .filterExpression(FILTER_EXPRESSION) .expressionAttributeNames(expressionAttributeNames) .expressionAttributeValues(expressionAttributeValues) .build(); return dynamoDbClient.query(queryRequest); }
Query with a dynamically constructed filter expression using AWS SDK for Java 2.x.
import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.dynamodb.DynamoDbClient; import software.amazon.awssdk.services.dynamodb.model.AttributeValue; import software.amazon.awssdk.services.dynamodb.model.DynamoDbException; import software.amazon.awssdk.services.dynamodb.model.QueryRequest; import software.amazon.awssdk.services.dynamodb.model.QueryResponse; import software.amazon.awssdk.services.dynamodb.model.ResourceNotFoundException; import java.util.HashMap; import java.util.Map; public static QueryResponse queryWithDynamicFilter( final String tableName, final String partitionKeyName, final String partitionKeyValue, final Map<String, Object> filterCriteria, final Region region, final DynamoDbClient dynamoDbClient) { validateParameters(tableName, partitionKeyName, partitionKeyValue, filterCriteria); DynamoDbClient ddbClient = dynamoDbClient; boolean shouldClose = false; try { if (ddbClient == null) { ddbClient = createClient(region); shouldClose = true; } final QueryWithDynamicFilter queryHelper = new QueryWithDynamicFilter(ddbClient); return queryHelper.queryWithDynamicFilter(tableName, partitionKeyName, partitionKeyValue, filterCriteria); } catch (ResourceNotFoundException e) { System.err.println("Table not found: " + tableName); throw e; } catch (DynamoDbException e) { System.err.println("Failed to execute dynamic filter query: " + e.getMessage()); throw e; } catch (Exception e) { System.err.println("Unexpected error during query: " + e.getMessage()); throw e; } finally { if (shouldClose && ddbClient != null) { ddbClient.close(); } } } public static void main(String[] args) { final String usage = """ Usage: <tableName> <partitionKeyName> <partitionKeyValue> <filterAttrName> <filterAttrValue> [region] Where: tableName - The Amazon DynamoDB table to query. partitionKeyName - The name of the partition key attribute. partitionKeyValue - The value of the partition key to query. filterAttrName - The name of the attribute to filter on. filterAttrValue - The value to filter by. region (optional) - The AWS region where the table exists. (Default: us-east-1) """; if (args.length < 5) { System.out.println(usage); System.exit(1); } final String tableName = args[0]; final String partitionKeyName = args[1]; final String partitionKeyValue = args[2]; final String filterAttrName = args[3]; final String filterAttrValue = args[4]; final Region region = args.length > 5 ? Region.of(args[5]) : Region.US_EAST_1; System.out.println("Querying items with dynamic filter: " + filterAttrName + " = " + filterAttrValue); try { // Using the builder pattern to create and execute the query final QueryResponse response = new DynamicFilterQueryBuilder() .withTableName(tableName) .withPartitionKeyName(partitionKeyName) .withPartitionKeyValue(partitionKeyValue) .withFilterCriterion(filterAttrName, filterAttrValue) .withRegion(region) .execute(); // Process the results System.out.println("Found " + response.count() + " items:"); response.items().forEach(item -> System.out.println(item)); // Demonstrate multiple filter criteria System.out.println("\nNow querying with multiple filter criteria:"); Map<String, Object> multipleFilters = new HashMap<>(); multipleFilters.put(filterAttrName, filterAttrValue); multipleFilters.put("status", "active"); final QueryResponse multiFilterResponse = new DynamicFilterQueryBuilder() .withTableName(tableName) .withPartitionKeyName(partitionKeyName) .withPartitionKeyValue(partitionKeyValue) .withFilterCriteria(multipleFilters) .withRegion(region) .execute(); System.out.println("Found " + multiFilterResponse.count() + " items with multiple filters:"); multiFilterResponse.items().forEach(item -> System.out.println(item)); } catch (IllegalArgumentException e) { System.err.println("Invalid input: " + e.getMessage()); System.exit(1); } catch (ResourceNotFoundException e) { System.err.println("Table not found: " + tableName); System.exit(1); } catch (DynamoDbException e) { System.err.println("DynamoDB error: " + e.getMessage()); System.exit(1); } catch (Exception e) { System.err.println("Unexpected error: " + e.getMessage()); System.exit(1); } }
Query with a filter expression and limit using AWS SDK for Java 2.x.
import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.dynamodb.DynamoDbClient; import software.amazon.awssdk.services.dynamodb.model.AttributeValue; import software.amazon.awssdk.services.dynamodb.model.DynamoDbException; import software.amazon.awssdk.services.dynamodb.model.QueryRequest; import software.amazon.awssdk.services.dynamodb.model.QueryResponse; import software.amazon.awssdk.services.dynamodb.model.ResourceNotFoundException; import java.util.HashMap; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; public QueryResponse queryWithFilterAndLimit( final String tableName, final String partitionKeyName, final String partitionKeyValue, final String filterAttrName, final String filterAttrValue, final int limit) { CodeSampleUtils.validateTableParameters(tableName, partitionKeyName, partitionKeyValue); CodeSampleUtils.validateStringParameter("Filter attribute name", filterAttrName); CodeSampleUtils.validateStringParameter("Filter attribute value", filterAttrValue); CodeSampleUtils.validatePositiveInteger("Limit", limit); // Create expression attribute names for the column names final Map<String, String> expressionAttributeNames = new HashMap<>(); expressionAttributeNames.put(EXPRESSION_ATTRIBUTE_NAME_PK, partitionKeyName); expressionAttributeNames.put(EXPRESSION_ATTRIBUTE_NAME_FILTER, filterAttrName); // Create expression attribute values for the column values final Map<String, AttributeValue> expressionAttributeValues = new HashMap<>(); expressionAttributeValues.put( EXPRESSION_ATTRIBUTE_VALUE_PK, AttributeValue.builder().s(partitionKeyValue).build()); expressionAttributeValues.put( EXPRESSION_ATTRIBUTE_VALUE_FILTER, AttributeValue.builder().s(filterAttrValue).build()); // Create the filter expression final String filterExpression = "#filterAttr = :filterValue"; // Create the query request final QueryRequest queryRequest = QueryRequest.builder() .tableName(tableName) .keyConditionExpression(KEY_CONDITION_EXPRESSION) .filterExpression(filterExpression) .expressionAttributeNames(expressionAttributeNames) .expressionAttributeValues(expressionAttributeValues) .limit(limit) .build(); try { final QueryResponse response = dynamoDbClient.query(queryRequest); LOGGER.log(Level.INFO, "Query with filter and limit successful. Found {0} items", response.count()); LOGGER.log( Level.INFO, "ScannedCount: {0} (total items evaluated before filtering)", response.scannedCount()); return response; } catch (ResourceNotFoundException e) { LOGGER.log(Level.SEVERE, "Table not found: {0}", tableName); throw e; } catch (DynamoDbException e) { LOGGER.log(Level.SEVERE, "Error querying with filter and limit: {0}", e.getMessage()); throw e; } }
-
For API details, see Query in AWS SDK for Java 2.x API Reference.
-