All The DynamoDB Query Methods And How They Work
A brief look at the various DynamoDB query methods supported and a look at how and when to use them.
Querying your database tables is made simple with DynamoDB’s API queries.
There are 11 query methods you can run against your tables and they are split by two different types.
Let’s examine these different query methods and understand what they are best used for.
DynamoDB Query Methods
The following seven methods can only be used on your primary key (sort key):
=
<
<=
>
>=
begins_with()
BETWEEN
The following four are methods that can be run on any attribute:
exists()
not_exists()
contains()
not_contains()
Equality Operators
Let’s start with the first five equality methods, =, <, < =, >, and > =.
Equality operators can be used on string or number type sort keys.
For example, if your sort keys are defined by unix timestamps like “1740941506”, you can use the following equality operators on the sort key to query your data.
KeyConditionExpression: "itemID = 101 AND date < 1740941506"
KeyConditionExpression: "itemID = 101 AND date <= 1740941506"
KeyConditionExpression: "itemID = 101 AND date > 1740941506"
KeyConditionExpression: "itemID = 101 AND date >= 1740941506"
KeyConditionExpression: "itemID = 101 AND date = 1740941506"
Any items whose date value matches the equality operation will be fetched.
This also works with strings as per an alphanumeric order.
The following query example is also valid:
KeyConditionExpression: "userID = "101" AND lastName > 'Smith' "
This will fetch all users whose names come after “Smith” in lexicographic order. (e.g. Snook would be included in the results).
And I can use “<” to get the last names of anything that comes before “Smith”.
So equality operators are a good fit for fetching sequential data with string or number values.
The begins_with() Method
The begins_with() query method is the basis of data filtering in DynamoDB.
This method lets you specify a prefix substring which will match your items’ sort key on your table. The items whose sort keys begin with the prefix you provide will be returned
Let’s see an example of using begins_with().
Imagine I need to query warehouses on my DynamoDB database.
I store my warehouse items with their location (city) in my sort key. With begins_with() I can get all warehouses in a given city:
KeyConditionExpression: "pk = 'warehouses#canada' AND begins_with(sk, 'montreal#') "
This query enables me to fetch all warehouses located in Montreal.
I can further filter that query to get all warehouses only within a specific region in Montreal:
KeyConditionExpression: "pk = 'warehouses#canada' AND begins_with(sk, 'montreal#ville-marie') "
You can also further filter by adding a zipcode if you need.
These queries of course depend on your sort key’s data modeling to be structured as “<city>#<region>#<zipcode>”.
The BETWEEN method
The BETWEEN method allows you to specify a starting string and an ending string and get back all items whose sort key falls between this range.
This enables range filters like dates and other sequence-based values.
Imagine we have a database that stores social media posts for users.
I can store post items under a user’s ID as the partition key and prefix the postID with the date it was published.
For example: userID: “101”, postID: “2025–03–02#post-1091”.
I can run the following query to fetch all posts published this month for that user:
KeyConditionExpression: "user = '101' AND postID BETWEEN '2025-03-01#' AND '2025-03-31' "
Using the between method allows me to specify a range of possible dates, which all posts in that month can fall under. The BETWEEN query will then return all posts for that month.
These are the queries that can be run on your sort keys only.
The last four query methods, also known as FilterExpressions, are queries that can be run on any item attribute in your table.
(Why use the first seven if they are limited to only the sort key? Read this article to understand why).
The exists() Method
The exists method allows you to filter items if a given attribute exists on them.
Here’s an example.
Imagine an e-commerce application database which needs to filter shipment data based on whether its been assigned a “status” attribute.
All shipments that have a status can be organized and displayed differently.
Here’s a FilterExpression query that will get us back this data.
KeyConditionExpression: "warehouse = '101'",
FilterExpression: 'exists(status)'
The not_exists() Method
We can also fetch data in the opposite manner.
We can query for all products that haven’t been shipped yet for example:
KeyConditionExpression: "warehouse = '101'",
FilterExpression: "not_exists(status)"
The contains() Method
The contains() method offers a more flexible method of filtering.
For the e-commerce example, say our products have tags on them.
For example: headphones may have ‘electronics’, ‘entertainment’ and ‘music’.
This tags data can be stored inside an array.
If we wish to fetch all items that have a ‘music’ tag in the tags array, we can run the following query:
KeyConditionExpression: "warehouse = '101'",
FilterExpression: "contains('music')"
The not_contains() Method
The not_contains method works the same way as the contains method.
Here you can specify a value which does not exist in the array.
For example, I can retrieve all items whose tags array does not have the value ‘kids’ to exclude kids toys, for example.
This offers some more flexibility than the others but may add some more latency and costs to your queries.
Conclusion
DynamoDB offers several different query methods that enable simple data retrieval, whether you’re working with sort keys or filtering attributes.
There are 11 query methods you can use, including:
equality operators
powerful filters like begins_wth()
range-based queries like BETWEEN
flexible filtering methods like contains(), not_contains(), exists() and not_exists()
Mastering these query techniques, and knowing when to use which, ensures you can design a DynamoDB database that meets your application’s needs while keeping your queries fast and cost-effective.
👋 My name is Uriel Bitton and I’m committed to helping you master Serverless, Cloud Computing, and AWS.
🚀 If you want to learn how to build serverless, scalable, and resilient applications, you can also follow me on Linkedin for valuable daily posts.
Thanks for reading and see you in the next one!