-
Notifications
You must be signed in to change notification settings - Fork 0
Expressions: Projection builder
See also (AWS JS SDK v3): Projection expressions · Expression attribute names. Vocabulary: Concepts.
Projection is the primary read-performance lever for DynamoDB. Items can carry dozens of attributes, some of them large — embedded blobs, serialized graphs, long text. A read that only needs two or three of them shouldn't pay the cost of transferring the full item. Projection tells DynamoDB which attributes to return; everything else stays on the server. Result: less read capacity consumed (especially on Scan / Query pages), less scan-byte pressure, less network egress back to your client.
Pair with patches on the write side for the symmetric win — read a slice, modify only what changed, write the delta. The fields you don't touch never leave the server either way.
addProjection(params, fields, projectionFieldMap?, skipSelect?, separator?) builds DynamoDB's ProjectionExpression from a list of fields, with attribute-name aliasing and de-duplication. It's an additive builder — mutates params in place and returns it.
import {addProjection} from 'dynamodb-toolkit/expressions';
const params = addProjection(
{/* existing params */},
['name', 'climate', 'terrain']
);
// ProjectionExpression: "#pj0,#pj1,#pj2"
// EAN: {#pj0: 'name', #pj1: 'climate', #pj2: 'terrain'}
// Select: 'SPECIFIC_ATTRIBUTES'function addProjection<T extends object>(
params: T,
fields?: string | string[] | Record<string, unknown> | null,
projectionFieldMap?: Record<string, string>,
skipSelect?: boolean,
separator?: string
): T;fields accepts:
-
'name,climate,terrain'(comma string) ['name', 'climate', 'terrain']-
{name: 1, climate: 1}(object — keys become fields) -
null/undefined/''— no-op, returns params unchanged
Pass skipSelect: true when you don't want Select: 'SPECIFIC_ATTRIBUTES' set (e.g., Select: 'COUNT' paths).
projectionFieldMap rewrites the first segment of each path:
addProjection({}, ['desc'], {desc: 'description'});
// EAN: {#pj0: 'description'}; ProjectionExpression: "#pj0"Use this when the wire-side name differs from the storage column name. The Adapter forwards its projectionFieldMap constructor option here.
If you call addProjection multiple times against the same params, duplicates are detected and the projection is collapsed:
let p = addProjection({}, ['name', 'climate']);
p = addProjection(p, ['climate', 'terrain']);
// ProjectionExpression: "#pj0,#pj1,#pj2" — climate not repeatedSame convention as the other builders — pure-digit segments become array indices:
addProjection({}, ['config.thresholds.0', 'tags.2']);
// ProjectionExpression: "#pj0.#pj1[0],#pj2[2]"The Adapter applies projection automatically in getByKey / getByKeys / getList / getListByParams when fields is supplied. Use addProjection directly when you're building params for applyTransaction / getBatch / a custom Query/Scan pipeline outside the Adapter.
Start here
- Getting started
- Concepts
- Key and field design
- Compatibility
- Migration: v2 to v3
- SDK v2 to v3 cheat sheet
Guides
- Hierarchical data walkthrough
- Key expression patterns
- Multi-type tables
- Pagination
- Mass operation semantics
- URL schema design
Adapter
- Adapter
- Constructor options
- CRUD methods
- Mass methods
- Batch builders
- Hooks
- Raw marker
- Indirect indices
- Transaction auto-upgrade
Expression builders
Batch / transactions / mass / paths
REST surface
Framework adapters
Recipes
- Recipes index
- List records of a tier
- Per-tier sparse GSI markers
- Tier within a partition
- Reservation with auto-release
- Keys-only GSI, runtime projection
- Cascade subtree operations
- Querying subtrees with buildKey
- Filter URL grammar
- Text search
- Provisioning workflow
- Resumable mass operations
History