Use expressions
DynamoDB Mapper provides Kotlin DSLs for building the two kinds of DynamoDB expressions you use most:
-
Filter and condition expressions: boolean conditions that narrow the results of a
queryorscan, or that gate a write. You build these in afilter { }block. -
Update expressions: instructions that describe how
updateItemmodifies an item. You build these in anupdate { }block.
This topic uses the Order item type (partition key customerId, sort key orderId) for its examples.
Important
These DSLs build low-level expressions: they are not restricted by or adherent to any defined schema. Instead, they are a convenience layer over literal DynamoDB expression strings and expression attribute value maps. As such they provide minimal type correctness and might allow you to form expressions that are invalid given the shape of your data, such as referencing attributes that don’t exist or comparing mismatched data types. Because they’re schema-unaware, expressions reference stored attribute names, not Kotlin property names. For example, a property annotated with @DynamoDbAttribute (such as @DynamoDbAttribute("created_at")) is referenced by its stored name: attr["created_at"].
Reference attributes
Every expression references at least one attribute through the attr accessor. A top-level attribute is attr["name"]. Nested values inside maps and lists are reached by chaining the [] operator with string keys and integer indexes:
attr["status"] // a top-level attribute attr["shipping"]["city"] // the "city" entry of the "shipping" map attribute attr["productSkus"][0] // the first element of the "productSkus" list attribute
Filter expressions
Set a filter { } on a query or scan to drop items that don’t match a condition. The filter is applied by DynamoDB after items are read, so it narrows results but doesn’t reduce read cost.
import aws.sdk.kotlin.hll.dynamodbmapper.expressions.KeyFilter val largeShipped = ordersTable .queryPaginated { keyCondition = KeyFilter("customer-123") filter { and( attr["status"] eq "SHIPPED", attr["totalCents"] gt 10_000L, ) } } .items()
Operators and functions
Inside a filter { } block, the following are available on attribute references.
Comparisons
The following equality/inequality comparison operators are available:
-
A eq B: true ifAis equal toB -
A gt B: true ifAis greater thanB -
A gte B: true ifAis greater than or equal toB -
A lt B: true ifAis less thanB -
A lte B: true ifAis less than or equal toB -
A neq B: true ifAis not equal toB
filter { attr["totalCents"] gte 5_000L } // totalCents is greater than or equal to 5,000
Ranges and membership
The following operators work on ranges and collections:
-
A.isBetween(B, C): true ifAis greater than or equal toBand less than or equal toC -
A isIn B: true ifAis an element in the collection/rangeB
filter { attr["totalCents"] isIn 1_000L..5_000L } // totalCents is between 1,000 and 5,000 filter { attr["status"] isIn setOf("PAID", "SHIPPED") } // status is either PAID or SHIPPED
Functions
The following functions are available:
-
A contains B: true ifAcontainsBas an element or substring -
A.exists(): true if the item contains attributeA -
A isOfType B: true ifA's attribute type isB -
A.notExists(): true if the item does not contain attributeA -
A.size: computes the string length or collection size ofA. Note that this is not a boolean expression and must be combined with another operator or function to form a valid filter expression. -
A startsWith B: true ifAbegins withB
filter { attr["productSkus"] contains "SKU-1" } // SKU-1 is an element in productSkus filter { attr["couponCode"].exists() } // the item has a couponCode filter { attr["orderId"] startsWith "ORDER#2026" } // orderId begins with ORDER#2026 filter { attr["productSkus"].size gte 2 } // there are at least 2 productSkus
Boolean logic
The following boolean logic operations are available:
-
and(A, B, C, …): true if all ofA,B,C,…are true -
or(A, B, C, …): true if at least one ofA,B,C,…is true -
not(A): true ifAis false; false ifAis true
filter { or( attr["status"] eq "PENDING", and( attr["status"] eq "PAID", not(attr["couponCode"].exists()), ), ) }
Key conditions
A query also takes a keyCondition, built with KeyFilter. Unlike a filter, a key condition is evaluated by DynamoDB to select which items to read. It always specifies the partition key and can add a condition on the sort key through a lambda argument:
// All orders for a customer: keyCondition = KeyFilter("customer-123") // Orders for a customer whose orderId begins with a prefix: keyCondition = KeyFilter("customer-123", { sortKey startsWith "ORDER#2026" })
Within the sort-key lambda you can use the following operators and functions:
-
Comparisons:
eq,gt,gte,lt,lte,neq -
Ranges and membership:
isBetweenandisIn -
Functions:
startsWith
Update expressions
Set an update { } on updateItem to modify an item in place without reading and rewriting it. An update expression contains one or more of four clauses, which may appear in any order:
-
add { }: increment numbers or add elements to sets -
delete { }: remove elements from sets -
remove { }: delete attributes or elements -
set { }: add or modify attributes
import aws.sdk.kotlin.hll.dynamodbmapper.items.Key ordersTable.updateItem { partitionKey = Key("customer-123") sortKey = Key("ORDER#2026-06-25#0042") update { set { attr["status"] = "SHIPPED" attr["totalCents"] = attr["totalCents"] - 500 // apply a $5.00 discount attr["notes"] = attr["notes"] orElse "none" // set only if not already present } remove { -attr["couponCode"] // remove the coupon code } add { attr["tags"] += setOf("priority") // add elements to the "tags" set } delete { attr["tags"] -= setOf("gift") // remove an element from the "tags" set } } }
Clause details
add
increments a number or adds elements to a set with +=. Unlike a set increment, this maps to the low-level ADD action, which also creates the attribute if it’s absent.
add { attr["tags"] += setOf("backordered") }
delete
removes elements from a set with -=:
delete { attr["tags"] -= setOf("gift", "priority") }
remove
deletes attributes, map entries, or list elements with the unary - operator:
remove { -attr["couponCode"] -attr["productSkus"][0] }
set
adds or replaces attributes and elements. Assign a literal value or an expression with =. Derive numeric values with +/- (or +=/-=), fall back to a default for a missing attribute with orElse, and concatenate lists with appending:
set { attr["status"] = "PAID" attr["totalCents"] += 250 attr["productSkus"] = attr["productSkus"] appending listOf("SKU-9") }
Related topics
-
Operations overview: the
query,scan, andupdateItemoperations these expressions feed. -
Use secondary indexes with DynamoDB Mapper: key conditions and filters on indexes.