Strategi filtering DynamoDB
"Filtering" di DynamoDB berarti empat hal berbeda dengan kata yang sama. Tiga
mempersempit data sebelum dibaca dan ditagih; satu — yang bernama Filter —
mempersempitnya sesudah. Mengetahui mana yang mana adalah sebagian besar
keterampilannya.
Bagaimana filtering bekerja di DynamoDB?
DynamoDB punya empat cara filter, dan hanya satu yang berjalan setelah Anda
ditagih. memilih partisi, sort key mempersempit
irisan, dan sparse index memfilter berdasarkan kehadiran atribut — ketiganya
memotong biaya baca sebelum metering. FilterExpression berjalan setelah baca,
jadi ia mengecilkan respons tetapi tidak pernah tagihan.
- adalah filter termurah: ia memilih partisi, jadi Anda tidak pernah menyentuh sisa tabel.
- memfilter di dalam partisi dengan
begins_with,between,<,>— masih sebelum billing, masih murah. - memfilter berdasarkan ketiadaan: item hanya muncul di indeks jika ia punya atribut yang diindeks, jadi indeks adalah set yang difilter.
FilterExpressionadalah jebakan: ia berjalan setelah DynamoDB mengukur baca, jadi ia memotong ukuran respons tetapi tidak pernah tagihan Anda.
Siapkan contohnya
Katalog produk. Satu tabel, partition key PK, sort key SK:
PK = "DEPT#kitchen" SK = "PROD#00194"
Setiap produk juga membawa price, inStock (boolean), dan clearanceAt
(timestamp unix, hanya hadir pada item yang ditandai clearance). Item dalam satu
department berbagi partisi, diurutkan berdasarkan product id.
Kita ingin empat access pattern. Masing-masing memetakan ke strategi filtering
berbeda — dan pilihan salah pada mana pun adalah Scan yang akan Anda bayar
selamanya.
Filter dengan partition key
"Beri saya setiap produk di kitchen." Partition key menjawab ini langsung:
Query PK = "DEPT#kitchen"
DynamoDB membaca tepat satu partisi. Tidak ada yang lain di tabel disentuh atau
ditagih. Ini satu-satunya filter yang gratis dalam arti yang penting — perbedaan
antara Query dan Scan.
Datang dari SQL, ini terasa terbalik: tidak ada WHERE department = 'kitchen'
yang men-scan indeks, Anda sekadar menamai partisi. Jika Anda tidak bisa
menaminya, itu masalah pemodelan, bukan masalah query.
Filter dengan sort key
"Beri saya produk kitchen dari PROD#00100 ke atas." Sort key mempersempit
di dalam partisi, dan melakukannya sebelum baca diukur:
Query PK = "DEPT#kitchen" AND SK between "PROD#00100" AND "PROD#00200"
Kondisi sort key dibatasi dengan sengaja: =, <, <=, >, >=, between,
dan begins_with. Tanpa OR, tanpa predikat arbitrer.
Batasan itulah yang menjaga baca tetap tertarget — DynamoDB menelusuri irisan kontigu, bukan seluruh partisi.
Tuas di sini adalah bagaimana Anda meng-encode sort key. Jika pola akses
Anda "berdasarkan rentang harga", sort key PROD#<id> tidak membantu — Anda
perlu memanggang harga ke dalam key.
Itu keputusan strategi sort key, dibuat saat desain, bukan saat query.
Filter dengan sparse index
"Beri saya semua yang sedang clearance." Sebagian besar produk tidak, jadi Anda tidak ingin membaca katalog untuk menemukan sedikit yang ya.
Sparse index menyelesaikan ini lewat ketiadaan. hanya berisi item jika item itu punya kedua atribut key indeks.
Set flag konstan clearance = "CLEARANCE" sebagai partition key GSI — ditulis
hanya pada item clearance — dengan clearanceAt sebagai sort key, dan indeks
tidak menampung yang lain.
AWS menjelaskannya: global secondary index hanya berisi item yang punya atribut key indeks, jadi item yang kehilangan atribut key sekadar tidak dipropagasi (AWS — Take advantage of sparse indexes).
Sekarang query hanya membaca item clearance, ditagih hanya untuk mereka:
Query ON ClearanceIndex GSI_PK = "CLEARANCE" (sorted by clearanceAt)
Filter terjadi saat Anda menulis data — dengan memilih apakah men-set
clearanceAt sama sekali. Indeks adalah set yang difilter. Lihat
GSI vs LSI untuk tipe indeks mana yang cocok.
Filter dengan FilterExpression
"Beri saya produk kitchen yang tersedia." inStock bukan atribut key, jadi
Anda menjangkau FilterExpression:
Query PK = "DEPT#kitchen"
Filter inStock = true
DynamoDB membaca setiap item di partisi kitchen, mengukur kapasitas untuk
semuanya, dan lalu membuang yang tidak tersedia.
AWS menyatakan filter expression "applied after a Query finishes, but before
the results are returned," dan "a Query consumes the same amount of read
capacity, regardless of whether a filter expression is present" — Anda sudah
membayar baca penuh (AWS — Filter expressions for Query).
Jadi jika kitchen punya 10.000 produk dan 12 tersedia, Anda membayar untuk
membaca 10.000. Respons kecil; tagihan tidak. FilterExpression mengecilkan
payload yang melintasi jaringan, bukan bacanya.
Ada tepi kedua yang lebih tajam: paginasi diukur sebelum filtering. Halaman adalah 1 MB item yang dibaca, bukan 1 MB yang cocok.
Filter bisa mengembalikan halaman kosong dengan LastEvaluatedKey ter-set —
DynamoDB membaca satu megabyte penuh, tidak cocok apa pun, menyerahkan array
kosong. Anda terus memaginasi, dan Anda membayar setiap halaman kosong.
Bangun expression — name, value, dan escaping reserved-word yang benar — dengan
DynamoDB Expression Builder agar
placeholder #inStock/:val benar pada percobaan pertama.
Builder di bawah di-preset ke Scan dengan FilterExpression — anti-pattern
tepat di atas. Perhatikan filter berjalan pada seluruh tabel, bukan irisan key:
Bandingkan keempatnya
| Kapan memfilter | Potong biaya baca? | Kekuatan predikat | Biaya setup | |
|---|---|---|---|---|
| Partition key | Sebelum baca | Ya — satu partisi | Equality saja | Gratis (itulah key) |
| Sort key | Sebelum baca | Ya — sebuah irisan | Range / begins_with | Desain sort key |
| Sparse index | Sebelum baca | Ya — hanya indeks | Kehadiran atribut | GSI ekstra + biaya tulis |
| FilterExpression | Setelah baca | Tidak | Hampir kondisi apa pun | Tidak ada |
Baca tabel dari atas ke bawah: kekuatan predikat naik, kontrol biaya turun.
FilterExpression bisa mengekspresikan apa pun justru karena berjalan pada item
yang sudah dibaca — alasan yang sama mengapa ia tidak bisa menghemat uang Anda.
Lihat di DynoTable
Saat Anda menjalankan Query dengan filter, celah antara item yang dibaca dan
item yang dikembalikan adalah seluruh ceritanya. DynoTable menampilkan item
yang di-scan di samping item yang dikembalikan saat baca berfilter streaming —
jadi filter yang diam-diam membaca seluruh partisi terlihat, bukan bersembunyi
di tagihan bulanan Anda.
Untuk pertanyaan lintas-item sungguhan yang filter tidak bisa jawab —
"harga rata-rata per department", "produk tersedia di-join ke ulasannya" — SQL
Workbench DynoTable menjalankan GROUP BY, JOIN, dan agregat di sisi klien
atas result set terbatas, alih-alih mengompilasi ke Scan seukuran tabel.
Jebakan dan langkah selanjutnya
- Jangan pakai
FilterExpressionsebagai jalur akses utama. Jika pattern umum, model ke key atau sparse index. Filter untuk sedikit penyempitan terakhir, bukan sebagian besarnya. - Perhatikan halaman kosong. Query berfilter bisa memaginasi lama
mengembalikan tidak ada. Hormati
LastEvaluatedKey; jangan asumsikan halaman kosong berarti "selesai". - Sparse index tidak gratis. Ia menelan kapasitas tulis dan penyimpanan untuk setiap item yang mendarat di dalamnya — murah saat atribut jarang, kurang saat tidak.
Perkirakan biaya baca berfilter dengan kalkulator harga, dan coba DynoTable untuk menyaksikan consumed capacity terhadap baris yang dikembalikan di tabel Anda sendiri.