Update Expression DynamoDB
Sebuah update expression memberi tahu UpdateItem cara memutasi satu Item: atribut
mana yang ditulis, dinaikkan, dihapus, atau dilipat ke dalam sebuah set. Tidak ada
UPDATE … SET … WHERE — Anda menamai Item dengan keynya dan mendeskripsikan
perubahan dengan empat keyword klausa.
Bagaimana cara kerja update expression DynamoDB?
Update expression DynamoDB memberi tahu UpdateItem cara memutasi satu item menggunakan empat klausa. SET menulis atau menimpa . ADD menaikkan angka secara atomik atau melakukan union ke dalam set. REMOVE menghapus atribut atau satu elemen list. DELETE menghapus member tertentu dari sebuah set. Satu panggilan dapat membawa keempat klausa sekaligus.
SETmenulis atau menimpa atribut — skalar, dokumen, dan idiom fungsiif_not_existssertalist_append.ADDmelakukan increment angka atomik atau union set, dalam satu round trip, tanpa baca-dulu.REMOVEmenghapus atribut sepenuhnya (atau satu elemen list berdasarkan index).DELETEmenghapus member tertentu dari sebuah set — dan hanya dari sebuah set.
Datang dari SQL, jebakannya adalah meraih SET untuk segalanya. ADD dan DELETE
ada karena read-modify-write pada counter atau set adalah race yang akan Anda kalahi
di bawah concurrency.
Pilih klausa berdasarkan apa yang Anda ubah
Satu panggilan UpdateItem bisa membawa keempat klausa sekaligus, dalam urutan
SET … REMOVE … ADD … DELETE. Setiap keyword muncul paling banyak sekali dan
mengambil daftar aksi yang dipisah koma.
| Klausa | Bekerja pada | Gunakan untuk |
|---|---|---|
SET | Atribut apa pun | Menulis/menimpa nilai atau field dokumen |
ADD | Number atau Set saja | Menaikkan secara atomik, atau union ke set |
REMOVE | Atribut atau elemen list apa pun | Menghapus atribut; menjatuhkan satu index list |
DELETE | Set saja | Menghapus member tertentu dari sebuah set |
ADD pada string dan DELETE pada skalar adalah error validasi, bukan no-op —
DynamoDB menolak seluruh panggilan. Menurut
referensi update-expression AWS,
ADD dibatasi pada number dan set, dan DELETE pada set.
Contoh nyata: keranjang belanja
Satu Item per keranjang, berkey CartPK = "CART#c-9f21" dan CartSK = "SUMMARY".
Ia melacak OrderTotal berjalan, sebuah list LineItems, string set PromoCodes,
dan sebuah ItemCount.
SET — menulis skalar dan dokumen
SET menimpa apa pun yang ada di sana. Tambahkan line item ke list dan naikkan
total dalam panggilan yang sama:
SET OrderTotal = :total,
LineItems = list_append(LineItems, :newItem),
UpdatedAt = :now
list_append(LineItems, :newItem) menambahkan ke ekor; balik argumennya —
list_append(:newItem, LineItems) — untuk menambahkan ke depan. Urutan argumen
adalah urutan konkatenasi, tak lebih dari itu.
Ada footgun di panggilan pertama itu: jika keranjangnya baru, LineItems belum ada,
dan list_append pada atribut yang hilang gagal. Jaga dengan if_not_exists:
SET LineItems = list_append(if_not_exists(LineItems, :empty), :newItem)
if_not_exists(LineItems, :empty) mengembalikan list saat ini jika ada, kalau tidak
fallback :empty (list kosong []). Itu membuat add pertama dan setiap add
berikutnya memakai expression yang sama — alasan nyata idiom ini ada.
ADD — naikkan count, secara atomik
Untuk menaikkan ItemCount, jangan membacanya, menambah satu di kode Anda, lalu
SET ia kembali. Itu lost-update race: dua add bersamaan keduanya membaca 3,
keduanya menulis 4, dan Anda kehilangan satu. ADD melakukan aritmetika di sisi
server:
ADD ItemCount :one
Dengan :one = 1, ini adalah counter atomik. Panggilan bersamaan terserialisasi
pada Item, jadi dua add mendarat sebagai +2. Lewatkan angka negatif untuk
mengurangi. Jika ItemCount absen, ADD memperlakukannya sebagai 0 lebih dulu —
jadi Anda tak perlu menyemai counter-nya.
Anda bisa membangun expression persisnya — nama, nilai bertipe, dan request yang
ter-marshal — di DynamoDB expression builder
tanpa meng-escape tangan satu pun placeholder #name atau :value.
REMOVE — jatuhkan atribut atau satu line item
REMOVE adalah cara Anda menghapus atribut sepenuhnya (tak ada "set ke null" — itu
hanya menulis tipe NULL). Bersihkan diskon yang diterapkan dan jatuhkan line item
ketiga dalam satu panggilan:
REMOVE AppliedDiscount, LineItems[2]
LineItems[2] menghapus elemen di index 2 dan menggeser segalanya setelahnya ke
bawah — index 3 menjadi 2, dan seterusnya. Jika Anda REMOVE dua index dalam satu
expression, keduanya dievaluasi terhadap list asli, jadi menghapus [2] dan
[3] bersama menjatuhkan elemen ketiga dan keempat seperti yang Anda harapkan.
DELETE — hapus member set
PromoCodes adalah string set, jadi customer yang menarik satu kode memakai
DELETE, bukan REMOVE. REMOVE PromoCodes akan melenyapkan seluruh set; DELETE
mengurangkan member yang disebut:
DELETE PromoCodes :pulled
Dengan :pulled = set {"SAVE10"}, hanya member itu yang pergi. Dua aturan
menggigit di sini: sebuah set tak pernah boleh kosong, jadi menghapus member
terakhir menghapus atribut PromoCodes sepenuhnya; dan nilainya harus berupa tipe
set yang cocok dengan atributnya — string telanjang adalah type error.
Satukan
Sebuah update "tambah item, terapkan promo, naikkan count" adalah satu panggilan melintasi tiga klausa:
SET LineItems = list_append(if_not_exists(LineItems, :empty), :newItem),
OrderTotal = OrderTotal + :price
ADD ItemCount :one
DELETE PromoCodes :expiredCode
Perhatikan OrderTotal = OrderTotal + :price — aritmetika di dalam SET bekerja
pada nilai yang ada. Ia tak atomik sebagaimana ADD untuk keamanan-race, tetapi ia
membaca total saat ini di sisi server alih-alih round-trip ia lewat kode Anda.
Jebakan yang harus dihindari
- Meng-
SETcounter yang Anda baca dulu. GunakanADD— read-modify-write kehilangan pembaruan di bawah concurrency. Ini bug keranjang/inventory paling umum. list_appendpada list yang hilang. Bungkus target denganif_not_existsatau penulisan pertama gagal.- Mengelirukan
REMOVEdanDELETE.REMOVEmenjatuhkan atributnya;DELETEmengurangkan member dari sebuah set. Mencampurnya menghapus lebih dari yang Anda maksud. - Melupakan
UpdateItemadalah upsert. Jika key-nya tak ada, ia membuat Item. GunakanConditionExpression(attribute_exists(CartPK)) saat Anda bermaksud "perbarui saja".
Untuk memodelkan key yang dijalani expression ini, lihat single-table design; untuk memutuskan cara Anda membaca kembali keranjang, lihat query vs scan.
Bangun dan salin salah satunya di expression builder, lalu coba DynoTable untuk menjalankannya terhadap tabel Anda sendiri dan menyaksikan Item berubah secara langsung.