DynamoDB Filter Expressions

After DynamoDB retrieves items using a Query or Scan, you can apply a Filter Expression to keep only the items that match specific conditions. This is a post-retrieval filter — DynamoDB fetches the data first and then applies the filter before returning results to you.

A Key Misunderstanding to Avoid

Many developers assume a Filter Expression tells DynamoDB which items to read. It does not. DynamoDB reads items based on the primary key (for Query) or the full table (for Scan). The Filter Expression only decides which of those read items to return to the caller.

This means Filter Expressions do not reduce read costs. You are charged for every item DynamoDB reads, whether it passes the filter or not.

Analogy

Imagine a restaurant bringing you the entire buffet on your table, and you pick only the dishes you like. You still pay for the full buffet. The Filter Expression is your picking — not the serving.

How Filter Expressions Work

Query: UserID = "U001"

DynamoDB fetches all items for U001:
┌──────────┬────────────┬──────────┬────────┐
│ UserID   │ OrderDate  │ Product  │ Amount │
├──────────┼────────────┼──────────┼────────┤
│ U001     │ 2024-01-05 │ Laptop   │ 85000  │  ← passes filter
│ U001     │ 2024-03-12 │ Mouse    │  1200  │  ← filtered out
│ U001     │ 2024-06-20 │ Monitor  │ 22000  │  ← passes filter
└──────────┴────────────┴──────────┴────────┘

FilterExpression: Amount > 10000

Result returned to you:
┌──────────┬────────────┬──────────┬────────┐
│ U001     │ 2024-01-05 │ Laptop   │ 85000  │
│ U001     │ 2024-06-20 │ Monitor  │ 22000  │
└──────────┴────────────┴──────────┴────────┘

DynamoDB read 3 items. You received 2. You were charged for 3.

Filter Expression Syntax

Filter Expressions use attribute names, comparison operators, and placeholder values. Placeholder names start with # and placeholder values start with :.

Basic Comparison Example

FilterExpression: "#amt > :minAmount"
ExpressionAttributeNames:  { "#amt": "Amount" }
ExpressionAttributeValues: { ":minAmount": { "N": "10000" } }

The # prefix is needed because Amount could conflict with a DynamoDB reserved word. Using #amt avoids any naming conflicts.

Supported Comparison Operators

OperatorMeaningExample
=Equal toStatus = "Delivered"
<>Not equal toStatus <> "Cancelled"
<Less thanAge < 18
<=Less than or equalPrice <= 500
>Greater thanScore > 90
>=Greater than or equalExperience >= 5
BETWEENWithin a rangePrice BETWEEN 100 AND 500
begins_withStarts with a stringProductName begins_with "Smart"
containsString or set contains valueTags contains "Electronics"
attribute_existsAttribute is present in the itemattribute_exists(Email)
attribute_not_existsAttribute is absent from the itemattribute_not_exists(DeletedAt)
attribute_typeAttribute is a specific data typeattribute_type(Price, N)
sizeLength of a string or setsize(Description) < 500

Combining Conditions

Use AND, OR, and NOT to combine multiple conditions.

Example: Active Premium Users

FilterExpression: "#status = :active AND #plan = :premium"

ExpressionAttributeNames:
  "#status": "AccountStatus"
  "#plan":   "Plan"

ExpressionAttributeValues:
  ":active":  { "S": "Active" }
  ":premium": { "S": "Premium" }

Example: Items That Are Not Cancelled

FilterExpression: "NOT #status = :cancelled"

ExpressionAttributeNames:  { "#status": "Status" }
ExpressionAttributeValues: { ":cancelled": { "S": "Cancelled" } }

Filter Expressions vs Key Conditions

FeatureKey Condition ExpressionFilter Expression
AppliedBefore reading from storageAfter reading from storage
Reduces read costYesNo
Can usePartition key and sort key onlyAny attribute
Available inQuery onlyQuery and Scan

Practical Example: Support Ticket System

TABLE: Tickets (PK: CustomerID, SK: TicketDate)

GOAL: Get open high-priority tickets for Customer C100 this year

Step 1 — Key Condition (efficient — reduces storage reads):
  CustomerID = "C100"
  AND TicketDate begins_with "2024"

Step 2 — Filter Expression (applied after storage read):
  Status = "Open" AND Priority = "High"

DynamoDB reads all 2024 tickets for C100 (maybe 40 tickets)
Returns only Open + High Priority ones (maybe 5 tickets)
Charge: 40 tickets read

When Filter Expressions Hurt Performance

Filter Expressions cause a problem with pagination. DynamoDB applies the 1 MB page limit before filtering. If DynamoDB reads 1 MB of data and the filter removes 90% of it, your page returns very few items even though you requested a full page. You might need many pagination rounds to collect enough results.

The fix: design your primary keys and indexes to pre-filter data at the key condition level, so the Filter Expression is never doing heavy lifting on large datasets.

Summary

  • Filter Expressions narrow down results after DynamoDB reads them from storage.
  • They do not reduce the number of items DynamoDB reads or the cost you pay.
  • Use key conditions (partition key and sort key) for the heavy filtering to minimize cost.
  • Apply Filter Expressions only for light additional filtering on small result sets.
  • Design your table keys and indexes to do the real work — not Filter Expressions.

Leave a Comment

Your email address will not be published. Required fields are marked *