DynamoDB
AWS SDK
Java
Query
Compound Key Condition Expression

With DynamoDb enhanced client from java aws sdk, how do you query using a compound keyConditionExpression?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

With the DynamoDB enhanced client, you do not usually build a raw string KeyConditionExpression the way you might with the low-level API. Instead, you express the key condition through QueryConditional, and that matters because the enhanced client only supports the key patterns DynamoDB itself allows: partition-key equality plus an optional sort-key condition.

What "Compound Key Condition" Means in DynamoDB

For a table with a composite primary key:

  • partition key must be tested with equality
  • sort key may use one additional condition such as =, BETWEEN, BEGINS_WITH, or range comparison

So the "compound" part is not an arbitrary boolean expression. It is specifically:

partitionKey = X plus one sort-key condition

If you need more filtering than that, use a filter expression in addition to the key condition, or redesign the key and index layout.

The Enhanced Client API Shape

With the enhanced client, you typically create:

  • a DynamoDbTable
  • a QueryConditional
  • optionally a QueryEnhancedRequest

For a query such as "all orders for customer C123 between two dates," the enhanced client code looks like this:

java
1import software.amazon.awssdk.enhanced.dynamodb.DynamoDbEnhancedClient;
2import software.amazon.awssdk.enhanced.dynamodb.DynamoDbTable;
3import software.amazon.awssdk.enhanced.dynamodb.Key;
4import software.amazon.awssdk.enhanced.dynamodb.TableSchema;
5import software.amazon.awssdk.enhanced.dynamodb.model.PageIterable;
6import software.amazon.awssdk.enhanced.dynamodb.model.QueryConditional;
7import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
8
9public class QueryExample {
10    public static void main(String[] args) {
11        DynamoDbClient lowLevel = DynamoDbClient.create();
12        DynamoDbEnhancedClient enhanced = DynamoDbEnhancedClient.builder()
13            .dynamoDbClient(lowLevel)
14            .build();
15
16        DynamoDbTable<Order> table =
17            enhanced.table("Orders", TableSchema.fromBean(Order.class));
18
19        QueryConditional conditional = QueryConditional.sortBetween(
20            Key.builder().partitionValue("C123").sortValue("2025-01-01").build(),
21            Key.builder().partitionValue("C123").sortValue("2025-12-31").build()
22        );
23
24        PageIterable<Order> results = table.query(r -> r.queryConditional(conditional));
25
26        results.items().forEach(System.out::println);
27    }
28}

The important detail is that both Key objects contain the same partition value, because DynamoDB queries stay within one partition at a time.

No .and(...) Chaining for QueryConditionals

One common mistake is trying to build the condition as if the enhanced client supported generic boolean composition. It does not work like:

java
keyEqualTo(...).and(sortBetween(...))

That is not the model. Instead, you use the appropriate QueryConditional factory for the exact supported key pattern:

  • 'keyEqualTo'
  • 'sortBetween'
  • 'sortBeginsWith'
  • 'sortGreaterThan'
  • 'sortGreaterThanOrEqualTo'
  • 'sortLessThan'
  • 'sortLessThanOrEqualTo'

Add a Filter Only When Needed

If you need non-key conditions, add a filter expression to the query request. That filter is evaluated after DynamoDB reads the matching key range, so it does not reduce the partition-key lookup scope the way a true key design would.

That means filter expressions are useful, but they are not a substitute for good table or GSI design.

Schema Design Still Comes First

If you find yourself wanting a much more complex KeyConditionExpression, it is often a sign that:

  • the partition key is too broad
  • the sort key is not shaped for the access pattern
  • a secondary index is needed

The enhanced client API reflects DynamoDB's design philosophy rather than hiding it.

Common Pitfalls

  • Trying to build an arbitrary boolean key condition in the enhanced client.
  • Forgetting that DynamoDB queries always require partition-key equality.
  • Using two different partition values in a sortBetween call.
  • Confusing filter expressions with key conditions.
  • Designing the query first and only later realizing the table key schema does not support it efficiently.

Summary

  • In the enhanced client, use QueryConditional, not a raw chained key-expression builder.
  • A DynamoDB query supports partition-key equality plus one optional sort-key condition.
  • 'sortBetween, sortBeginsWith, and the range comparison helpers cover the usual composite-key cases.'
  • Extra non-key predicates belong in filter expressions or, better, in a better index design.
  • If the query feels too complex for QueryConditional, the data model is often the real issue.

Course illustration
Course illustration

All Rights Reserved.