VOOZH about

URL: https://www.javacodegeeks.com/query-dynamodb-with-hashkey-and-range-key.html

⇱ Query DynamoDB with Hashkey And Range Key - Java Code Geeks


Amazon DynamoDB is a fully managed NoSQL database service designed for high availability and low latency at any scale. It uses a key-value and document data model and is widely used for serverless and scalable applications. Let us delve into understanding how to query DynamoDB using a hashkey and range key.

1. Introduction to DynamoDB

Amazon DynamoDB is a fully managed NoSQL database service provided by AWS that offers high performance at scale with seamless horizontal scaling, low-latency reads/writes, and automatic replication across multiple Availability Zones.

DynamoDB organizes data into tables, where each table requires a uniquely defined Primary Key. The primary key plays a critical role in uniquely identifying each item in the table and directly influences data access patterns.

There are two types of primary keys supported by DynamoDB:

  • Simple Primary Key: Consists of only a Partition Key (also called HASH key). Each item in the table is uniquely identified by this partition key.
  • Composite Primary Key: Consists of a Partition Key and a Sort Key (also called HASH + RANGE). This enables multiple items with the same partition key but different sort keys to exist, allowing finer granularity and logical grouping.

You can learn more about how primary keys work in DynamoDB.

Querying in DynamoDB becomes especially powerful with the use of a composite primary key. When you query using a Partition Key and Sort Key combination, you can:

  • Efficiently retrieve all items with the same partition key.
  • Apply key condition expressions to filter based on the Sort Key (e.g., greater than, begins_with, between).
  • Perform range queries using the Sort Key to fetch items in a specific logical order or range.

This makes DynamoDB an excellent choice for use cases such as time-series data, user activity tracking, order history, and more, where data naturally fits into grouped and ordered records.

1.1 DynamoDB Setup on Docker and Mock Data Setup

1.1.1 Start Local DynamoDB using Docker

To begin experimenting with DynamoDB locally, you can use the official DynamoDB Local Docker image provided by AWS. This eliminates the need to interact with the actual AWS cloud during development and testing, making it faster and cost-effective.

Run the following Docker command to start a local DynamoDB instance on port 8000:

docker run -p 8000:8000 amazon/dynamodb-local

1.1.2 Create Table with Composite Key and Insert Sample Data

Once the local DynamoDB is up and running, the next step is to create a table with a composite primary key, consisting of a CustomerId as the Partition Key and OrderDate as the Sort Key.

-- Following AWS CLI command will create a table.

aws dynamodb create-table \
 --table-name Orders \
 --attribute-definitions AttributeName=CustomerId,AttributeType=S AttributeName=OrderDate,AttributeType=S \
 --key-schema AttributeName=CustomerId,KeyType=HASH AttributeName=OrderDate,KeyType=RANGE \
 --provisioned-throughput ReadCapacityUnits=5,WriteCapacityUnits=5 \
 --endpoint-url http://localhost:8000

-- After creating the table, you can insert some sample data.

aws dynamodb batch-write-item --request-items '{
 "Orders": [
 {
 "PutRequest": {
 "Item": {
 "CustomerId": {"S": "CUST001"},
 "OrderDate": {"S": "2024-06-01"},
 "Amount": {"N": "100"}
 }
 }
 },
 {
 "PutRequest": {
 "Item": {
 "CustomerId": {"S": "CUST001"},
 "OrderDate": {"S": "2024-06-05"},
 "Amount": {"N": "200"}
 }
 }
 },
 {
 "PutRequest": {
 "Item": {
 "CustomerId": {"S": "CUST001"},
 "OrderDate": {"S": "2024-06-10"},
 "Amount": {"N": "300"}
 }
 }
 }
 ]
}' --endpoint-url http://localhost:8000

The snippet demonstrates how to create and populate a DynamoDB table named Orders using the AWS CLI while working with a local DynamoDB instance.

  • The create-table command sets up the table with a composite primary key, where CustomerId serves as the partition key (HASH) and OrderDate as the sort key (RANGE). Both attributes are defined as strings. The table is configured with provisioned throughput settings of 5 read and 5 write capacity units.
  • After the table is successfully created, the batch-write-item command is used to insert multiple records into the table in a single operation. These records represent orders placed by customer CUST001 on three different dates with corresponding amounts of 100, 200, and 300.
  • The --endpoint-url option points to http://localhost:8000, indicating that these operations are performed on a locally running DynamoDB instance, typically started using Docker.

2. Java Code Examples for Querying

Now that you have a DynamoDB table with sample data locally running, it’s time to interact with it using Java. This section covers how to set up the required SDK dependencies and implement a basic Java program to query the Orders table using a partition key and optionally filter by sort key.

2.1 Add Dependency

To communicate with DynamoDB from a Java application, you’ll need to include the AWS SDK for DynamoDB. If you are using Maven as your build tool, add the following dependency to your pom.xml:

<dependency>
 <groupId>software.amazon.awssdk</groupId>
 <artifactId>dynamodb</artifactId>
 <version>latest__jar__version</version>
</dependency>

2.2 Code Example

The following Java code demonstrates how to initialize a DynamoDB client, build a query request using a partition key (e.g., CustomerId), and retrieve the matching items. It assumes you are working with the locally hosted DynamoDB instance.

//DynamoDBQueryExample.java

import software.amazon.awssdk.auth.credentials.AnonymousCredentialsProvider;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
import software.amazon.awssdk.services.dynamodb.model.*;

import java.net.URI;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class DynamoDBQueryExample {

 public static void main(String[] args) {
 // Create DynamoDB client
 DynamoDbClient dynamoDb = DynamoDbClient.builder()
 .endpointOverride(URI.create("http://localhost:8000")) // Local Docker
 .region(Region.US_EAST_1)
 .credentialsProvider(AnonymousCredentialsProvider.create()) // For local
 .build();

 System.out.println("Querying orders for CUST001 after 2024-06-01...");

 Map<String, AttributeValue> expressionValues = new HashMap<>();
 expressionValues.put(":custId", AttributeValue.fromS("CUST001"));
 expressionValues.put(":startDate", AttributeValue.fromS("2024-06-01"));

 QueryRequest request = QueryRequest.builder()
 .tableName("Orders")
 .keyConditionExpression("CustomerId = :custId AND OrderDate >= :startDate")
 .expressionAttributeValues(expressionValues)
 .limit(2) // Enable pagination demo
 .build();

 QueryResponse response = dynamoDb.query(request);
 printItems(response.items());

 // Handle pagination
 while (response.hasLastEvaluatedKey()) {
 request = request.toBuilder()
 .exclusiveStartKey(response.lastEvaluatedKey())
 .build();
 response = dynamoDb.query(request);
 printItems(response.items());
 }

 dynamoDb.close();
 }

 private static void printItems(List<Map<String, AttributeValue>> items) {
 for (Map<String, AttributeValue> item : items) {
 System.out.println("CustomerId: " + item.get("CustomerId").s());
 System.out.println("OrderDate : " + item.get("OrderDate").s());
 System.out.println("Amount : " + item.get("Amount").n());
 System.out.println("-----");
 }
 }
}

2.2.1 Code Explanation

The DynamoDBQueryExample class demonstrates how to query a local DynamoDB table named Orders using the AWS SDK for Java. It first creates a DynamoDbClient configured to point to a locally running DynamoDB instance (using endpointOverride with http://localhost:8000) and anonymous credentials for local access. The application prints a message indicating it is querying orders for the customer CUST001 where the OrderDate is on or after 2024-06-01. It constructs a QueryRequest using a keyConditionExpression with both the partition key (CustomerId) and a range condition on the sort key (OrderDate >= :startDate). The query is limited to two results per page using the limit(2) setting to demonstrate pagination. After the initial query, the code checks for more results using hasLastEvaluatedKey() and continues fetching the remaining pages by updating the request with exclusiveStartKey. For each page, it calls the printItems() method, which iterates over the result items and prints CustomerId, OrderDate, and Amount fields for each order. Finally, the DynamoDB client is closed to release resources.

2.2.2 Code Output

Upon execution, the code produces the following output:

Querying orders for CUST001 after 2024-06-01...
CustomerId: CUST001
OrderDate : 2024-06-01
Amount : 100
-----
CustomerId: CUST001
OrderDate : 2024-06-05
Amount : 200
-----
CustomerId: CUST001
OrderDate : 2024-06-10
Amount : 300
-----

3. Conclusion

Querying in DynamoDB using Partition and Sort keys allows developers to structure their data access patterns efficiently. Whether you are retrieving all orders for a customer or filtering by date ranges, DynamoDB provides powerful query capabilities. By leveraging Docker for local development and Java SDK for integration, teams can build robust serverless applications with predictable and scalable query performance.

Do you want to know how to develop your skillset to become a Java Rockstar?
Subscribe to our newsletter to start Rocking right now!
To get you started we give you our best selling eBooks for FREE!
1. JPA Mini Book
2. JVM Troubleshooting Guide
3. JUnit Tutorial for Unit Testing
4. Java Annotations Tutorial
5. Java Interview Questions
6. Spring Interview Questions
7. Android UI Design
and many more ....
I agree to the Terms and Privacy Policy

Thank you!

We will contact you soon.

πŸ‘ Photo of Yatin Batra
Yatin Batra
June 23rd, 2025Last Updated: June 23rd, 2025
0 315 5 minutes read

Yatin Batra

An experience full-stack engineer well versed with Core Java, Spring/Springboot, MVC, Security, AOP, Frontend (Angular & React), and cloud technologies (such as AWS, GCP, Jenkins, Docker, K8).
Subscribe

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Oldest
Newest Most Voted
Back to top button
Close
wpDiscuz