Menengah5 menit baca

Ekspresi Pembaruan DynamoDB: SET, REMOVE, ADD, DELETE (dengan Contoh)

Ekspresi pembaruan memberi tahu UpdateItem cara memutasi satu item: yang mana untuk menulis, menambah, menghapus, atau melipat menjadi satu set. Tidak ada multi-baris UPDATE … SET … WHERE — Anda memberi nama satu item dengan kunci lengkapnya dan describe ubah dengan kata kunci empat klausa.

Bagaimana cara kerja ekspresi pembaruan DynamoDB?

Ekspresi pembaruan DynamoDB memberi tahu UpdateItem cara mengubah satu item menggunakan empat klausa. SET menulis atau menimpa . ADD secara atom menambah angka atau gabungan menjadi satu set. REMOVE menghapus atribut atau satu elemen daftar. DELETE menghapus anggota tertentu dari suatu kumpulan. Satu panggilan dapat membawa keempatnya sekaligus.

  • SET menulis atau menimpa atribut — skalar, dokumen, dan idiom fungsi if_not_exists dan list_append.
  • ADD melakukan kenaikan nomor atom atau gabungan himpunan, dalam satu perjalanan bolak-balik, tanpa baca dulu.
  • REMOVE menghapus atribut secara langsung (atau satu elemen daftar berdasarkan indeks).
  • DELETE menghapus anggota tertentu dari suatu kumpulan — dan hanya dari satu kumpulan.

Berasal dari SQL, jebakannya adalah meraih SET untuk segalanya. ADD dan DELETE ada karena baca-modifikasi-tulis pada counter atau set adalah perlombaan yang akan Anda lakukan kalah dalam konkurensi.

Pilih klausa berdasarkan apa yang Anda ubah

Satu panggilan UpdateItem dapat membawa keempat klausa sekaligus, dalam urutan apa pun. Masing-masing kata kunci muncul paling banyak satu kali dan mengambil daftar tindakan yang dipisahkan koma.

AyatBekerja padaGunakan untuk
SETAtribut apa punMenulis/menimpa bidang nilai atau dokumen
ADDHanya Nomor atau SetKenaikan secara atom, atau penggabungan menjadi satu set
REMOVEAtribut atau elemen daftar apa punHapus atribut; jatuhkan satu indeks daftar
DELETESetel sajaHapus anggota tertentu dari kumpulan

ADD pada string dan DELETE pada skalar adalah kesalahan validasi, bukan tanpa operasi — DynamoDB menolak seluruh panggilan. Menurut Referensi ekspresi pembaruan AWS, ADD terbatas pada angka dan set, dan DELETE terbatas pada set.

Contoh yang berhasil: keranjang belanja

Satu item per keranjang, dikunci oleh CartPK = "CART#c-9f21" dan CartSK = "SUMMARY". Ini melacak OrderTotal yang sedang berjalan, daftar LineItems, kumpulan string PromoCodes, dan ItemCount.

SET — menulis skalar dan dokumen

SET menimpa apa pun yang ada di sana. Tambahkan item baris ke daftar dan ubah total dalam panggilan yang sama:

SET OrderTotal = :total,
LineItems = list_append(LineItems, :newItem),
UpdatedAt = :now

list_append(LineItems, :newItem) ditambahkan ke ekor; balikkan argumen - list_append(:newItem, LineItems) — untuk menambahkan. Urutan argumennya adalah urutan penggabungan, tidak lebih.

Ada keuntungan dalam panggilan pertama itu: jika gerobaknya baru, LineItems belum ada, dan list_append pada atribut yang hilang gagal. Jagalah dengan if_not_exists:

SET LineItems = list_append(if_not_exists(LineItems, :empty), :newItem)

if_not_exists(LineItems, :empty) mengembalikan daftar saat ini jika ada, jika tidak fallback :empty (daftar kosong []). Itu membuat penambahan pertama dan berikutnya tambahkan gunakan ekspresi yang sama — alasan sebenarnya keberadaan idiom ini.

TAMBAHKAN — menambah hitungan, secara atom

Untuk mengganti ItemCount, jangan jangan membacanya, tambahkan satu di kode Anda, dan SET kembali. Itu adalah perlombaan pembaruan yang hilang: dua penambahan bersamaan keduanya membaca 3, keduanya menulis 4, dan kamu telah menjatuhkan satu. ADD melakukan aritmatika di sisi server:

ADD ItemCount :one

Dengan :one = 1, ini adalah penghitung atom. Panggilan serentak diserialkan di item, jadi dua menambahkan tanah sebagai +2. Berikan angka negatif untuk dikurangi. Jika ItemCount tidak ada, ADD memperlakukannya sebagai 0 terlebih dahulu — jadi Anda tidak perlu melakukan seeding konter.

Berdasarkan permintaan di us-east-1, setiap ADD menagih 1 WCU per KB item setelahnya tulisannya (dibulatkan). Ringkasan keranjang 1 KB dengan satu biaya ADD ItemCount :one 1 WCU — baris yang sama dengan SET baca-modifikasi-tulis akan dikenakan biaya WCU yang sama tapi kalah dalam konkurensi. Ukuran item di kalkulator ukuran item.

Anda dapat membuat ekspresi yang tepat ini — nama, nilai yang diketik, dan susunannya permintaan — di Pembuat ekspresi DynamoDB tanpa hand-escaping satu placeholder #name atau :value.

Edit preset di bawah — SET ditambah ADD atomik — dan tonton UpdateExpression dibangun kembali seiring berjalannya waktu:

Bangun request Anda
Kode yang dihasilkan
new UpdateItemCommand({
  "TableName": "AuditLog",
  "Key": {
    "pk": {
      "S": "TENANT#acme"
    },
    "sk": {
      "S": "CONFIG"
    }
  },
  "UpdateExpression": "SET #upd0 = :updValue0 ADD #upd1 :updValue1",
  "ExpressionAttributeNames": {
    "#upd0": "plan",
    "#upd1": "seats"
  },
  "ExpressionAttributeValues": {
    ":updValue0": {
      "S": "pro"
    },
    ":updValue1": {
      "N": "5"
    }
  }
})

HAPUS — hapus atribut atau satu item baris

REMOVE adalah cara Anda menghapus seluruh atribut (tidak ada "setel ke nol" — yang hanya menulis tipe NULL). Hapus diskon yang diterapkan dan hilangkan diskon ketiga item baris dalam satu panggilan:

REMOVE AppliedDiscount, LineItems[2]

LineItems[2] menghapus elemen pada indeks 2 dan menggeser semuanya setelahnya turun — indeks 3 menjadi 2, dan seterusnya. Jika Anda REMOVE dua indeks dalam satu ekspresi, keduanya dievaluasi berdasarkan daftar asli, jadi hapus [2] dan [3] bersama-sama menghilangkan elemen ketiga dan keempat seperti yang Anda harapkan.

HAPUS — menghapus anggota kumpulan

PromoCodes adalah kumpulan string, jadi pelanggan yang menarik satu kode menggunakan DELETE, bukan REMOVE. REMOVE PromoCodes akan menghancurkan seluruh rangkaian; DELETE mengurangi nama anggota:

DELETE PromoCodes :pulled

Dengan :pulled = himpunan {"SAVE10"}, hanya anggota tersebut yang masuk. Dua aturan menggigit di sini: suatu himpunan tidak boleh kosong, jadi menghapus anggota terakhir akan menghapusnya Atribut PromoCodes langsung; dan nilainya harus berupa tipe set yang cocok dengan atribut — string kosong adalah kesalahan tipe.

Gabungkan

Pembaruan "tambah item, terapkan promo, tambah jumlah" adalah satu panggilan dari tiga panggilan klausa:

SET LineItems = list_append(if_not_exists(LineItems, :empty), :newItem),
OrderTotal = OrderTotal + :price
ADD ItemCount :one
DELETE PromoCodes :expiredCode

Catatan OrderTotal = OrderTotal + :price — aritmatika di dalam SET berfungsi di nilai yang ada. Ini sama atomik dan amannya balapan seperti yang dievaluasi oleh ADD: DynamoDB Sisi server OrderTotal + :price terhadap nilai saat ini, jadi panggilan bersamaan membuat serial pada item alih-alih menelusuri kode Anda.

Jebakan yang harus dihindari

  • SET pada penghitung yang Anda baca terlebih dahulu. Gunakan ADD — baca-modifikasi-tulis kalah pembaruan secara bersamaan. Ini adalah bug keranjang/inventaris yang paling umum.
  • list_append pada daftar hilang. Bungkus target dalam if_not_exists atau penulisan pertama gagal.
  • Membingungkan REMOVE dan DELETE. REMOVE menghilangkan atributnya; DELETE mengurangkan anggota dari suatu himpunan. Mencampurnya akan menghapus lebih dari yang Anda maksudkan.
  • Melupakan UpdateItem adalah sebuah kesalahan. Jika kuncinya tidak ada, maka kunci tersebut akan dibuat barang tersebut. Gunakan ConditionExpression (attribute_exists(CartPK)) saat Anda berarti "perbarui saja".

Untuk memodelkan kunci yang digunakan oleh ekspresi ini, lihat desain meja tunggal; untuk memutuskan bagaimana Anda akan membaca troli kembali, lihat query vs scan.

Bangun dan salin semua ini di pembuat ekspresi, lalu coba DynoTable untuk menjalankannya di tabel Anda sendiri dan lihat itemnya berubah secara langsung.

Diperbarui