Unified Select
Mizzle’s “Unified Select” is an abstraction layer over DynamoDB’s GetItem, Query, and Scan operations. Instead of manually choosing which low-level operation to use, you express what you want (using .where()), and Mizzle determines the most efficient way to fetch it.
How Routing Works
Section titled “How Routing Works”When you call .execute() or .iterator(), Mizzle analyzes your query configuration:
-
Primary Key Match (
GetItem):- If your
.where()clause provides exact equality matches for both the Partition Key (PK) and Sort Key (SK) of the table. - Result: Uses
GetItem. Most efficient.
- If your
-
Index/Partition Match (
Query):- If your
.where()clause matches the PK of the table (but not the SK). - OR if it matches the PK of a Global Secondary Index (GSI).
- Result: Uses
Query. Efficient for collections of items.
- If your
-
Fallback (
Scan):- If no keys can be resolved from your filters.
- Result: Uses
Scan. Iterates the entire table. Least efficient.
Forcing Indexes
Section titled “Forcing Indexes”Sometimes Mizzle might default to a Scan or the main table when you intend to use a specific index (e.g., if your filter matches multiple potential indexes). You can enforce a specific path:
// Forces usage of the 'GSI1' index.// If the filter doesn't match GSI1's keys, this will throw or result in an empty query.await db.select().from(users).index("GSI1").where(eq(users.email, "test@example.com")).execute();Auto-Pagination & Iterators
Section titled “Auto-Pagination & Iterators”DynamoDB queries are paginated by default (1MB limit). Mizzle handles this transparently with Async Iterators.
const query = db.select().from(orders).where(eq(orders.status, "PENDING"));
// Automatically fetches pages as you loopfor await (const order of query.iterator()) { console.log(order.id);}Page Size vs Limit
Section titled “Page Size vs Limit”.pageSize(n): Hints DynamoDB to returnnitems per network request. Useful for controlling memory usage or throughput..limit(n): Stops the iterator afternitems are yielded, regardless of how many pages are fetched.
await db .select() .from(logs) .pageSize(100) // Fetch 100 at a time from AWS .limit(500) // Stop after processing 500 total .execute(); // .execute() automatically aggregates all pages up to the limitConsistency
Section titled “Consistency”By default, DynamoDB reads are “Eventually Consistent”. You can request “Strongly Consistent” reads (consuming 2x capacity) if you need to see the absolute latest data immediately after a write.
await db .select() .from(users) .where(eq(users.id, "123")) .consistentRead() // Enable strong consistency .execute();Note: Consistent reads are generally supported on the main table and Local Secondary Indexes (LSIs), but NOT on Global Secondary Indexes (GSIs).