DynamoDB
Query
Filtering
Database
AWS

How to query DynamoDB filtering by value in a list

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

Introduction

Amazon DynamoDB is a highly scalable and managed NoSQL database service provided by AWS (Amazon Web Services) designed for applications requiring fast and predictable performance. One of the challenging aspects of using DynamoDB is effectively querying and filtering data, especially when dealing with complex data types such as lists. This article will delve into how to query DynamoDB by filtering based on values present in a list.

Understanding DynamoDB Data Types

DynamoDB supports several data types including:

  • Scalar Types: Number, String, Binary, Boolean, and Null.
  • Document Types: List and Map.
  • Set Types: String Set, Number Set, and Binary Set.

For this discussion, our focus will be on the List, a flexible document data type that can hold a collection of various elements, including other Lists, Maps, or Scalar Types.

Setup Scenarios

Example Table

Consider the scenario where we have a DynamoDB table named Movies. This table includes an attribute named Genres which is of List type.

MovieIDTitleGenres
1Inception["Action", "Thriller", "Sci-Fi"]
2Titanic["Drama", "Romance", "History"]
3Matrix["Action", "Sci-Fi", "Adventure"]
4Gladiator["Action", "Adventure", "Drama"]

Objective

We aim to query the Movies table to find all movies that fall under specific genres, such as "Action".

Querying DynamoDB - Filter with Lists

DynamoDB’s query operations are designed to retrieve data quickly based on primary key attributes. However, when you need to filter data on attributes beyond the primary key, such as elements within a List, you'll often use a "Scan" operation combined with a "FilterExpression".

Using Scan with FilterExpression

A Scan operation examines every item in the table and returns all data attributes by default. To filter data based on the elements in the List, we use the contains function within a FilterExpression.

Example: Fetch All "Action" Movies

Here’s a sample code snippet using AWS SDK for JavaScript to perform this operation:

javascript
1const AWS = require("aws-sdk");
2const dynamodb = new AWS.DynamoDB.DocumentClient();
3
4const params = {
5    TableName: "Movies",
6    FilterExpression: "contains(Genres, :genre)",
7    ExpressionAttributeValues: {
8        ":genre": "Action"
9    },
10};
11
12dynamodb.scan(params, (err, data) => {
13    if (err) {
14        console.error("Unable to scan the table. Error JSON:", JSON.stringify(err, null, 2));
15    } else {
16        console.log("Scan succeeded.");
17        data.Items.forEach(item => console.log("Item :", JSON.stringify(item, null, 2)));
18    }
19});

Considerations

  1. Efficiency: A scan operation reads every item in the table which can be inefficient for larger datasets.
  2. Cost: Because of its exhaustive nature, Scan can be more expensive depending on the volume of data. Consider projecting only necessary attributes or utilizing pagination.
  3. FilterExpression Limitations: The contains function is suitable for List and String Set types, not for arbitrary querying of any data types.

Alternative Approaches

Using Global Secondary Indexes (GSI)

For more efficient queries, especially in production environments, consider using Global Secondary Indexes. However, GSIs are limited to scalar attributes and cannot index lists of strings directly. If possible, refactor your data model to utilize GSIs for more performant queries.

Batch Processing with Pagination

When using Scan, incorporate pagination to process large datasets efficiently by controlling the Limit parameter and handling LastEvaluatedKey.

Summary Table

Key TopicDescription
Data TypeDynamoDB List stores multiple values including other lists, maps, or scalar types.
Query MethodUse Scan with FilterExpression containing contains to filter list attributes.
Efficiency ConcernsScans read the entire table and can be inefficient for large data sets.
Cost ImplicationsCan be costly due to full table scans; use projection and pagination to mitigate.
OptimizationUse Global Secondary Indexes where applicable to increase efficiency.
PaginationUse it to handle high volume data effectively in Scan operations.

Conclusion

Filtering data in DynamoDB when working with complex data types like Lists involves creative and resource-aware techniques. Understanding the constraints and costs of different operations can help you make informed decisions on how to best query your data. Consider the trade-offs between using Scan and potential alternatives like GSIs, and always plan your data model for scalable performance.


Related reading
Course
Beginner
27 lessons
10 hours
System Design Fundamentals

Build a strong foundation in designing scalable, reliable distributed systems.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design