DynamoDB Query di Go (AWS SDK v2)
Query membaca satu partisi, secara opsional dipersempit oleh sort key (Query vs Scan membahas kapan itu pilihan yang tepat, dan key condition expression mendaftar setiap operator yang sah). Yang ditambahkan AWS SDK for Go v2 adalah QueryPaginator, yang mengubah loop LastEvaluatedKey menjadi sebuah loop for dan, sambil melakukannya, diam-diam menghapus kesempatan Anda untuk berhenti.
Kode
package main
import (
"context"
"fmt"
"log"
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/service/dynamodb"
"github.com/aws/aws-sdk-go-v2/service/dynamodb/types"
)
func main() {
ctx := context.TODO()
cfg, err := config.LoadDefaultConfig(ctx, config.WithRegion("us-east-1"))
if err != nil {
log.Fatalf("load config: %v", err)
}
client := dynamodb.NewFromConfig(cfg)
paginator := dynamodb.NewQueryPaginator(client, &dynamodb.QueryInput{
TableName: aws.String("Music"),
KeyConditionExpression: aws.String(
"#hashKey = :hashKeyValue AND begins_with(#rangeKey, :rangeKeyValue)"),
ExpressionAttributeNames: map[string]string{
"#hashKey": "Artist",
"#rangeKey": "SongTitle",
},
ExpressionAttributeValues: map[string]types.AttributeValue{
":hashKeyValue": &types.AttributeValueMemberS{Value: "Arturo Sandoval"},
":rangeKeyValue": &types.AttributeValueMemberS{Value: "C"},
},
})
var items []map[string]types.AttributeValue
for paginator.HasMorePages() {
page, err := paginator.NextPage(ctx)
if err != nil {
log.Fatalf("query: %v", err)
}
items = append(items, page.Items...)
}
fmt.Printf("Found %d items\n", len(items))
}Penjelasan
Limit tidak membatasi apa yang dibaca paginator. Inilah yang memakan biaya. Menyetel Limit: aws.Int32(5) pada input di atas lalu menjalankannya atas partisi berisi 30 item berukuran ~60 KB masing-masing menghasilkan:
page 1: Count=5 CU=37.0 page 5: Count=5 CU=37.0
page 2: Count=5 CU=37.0 page 6: Count=5 CU=37.0
page 3: Count=5 CU=37.0 page 7: Count=0 CU=0.0
page 4: Count=5 CU=37.0 total: 30 items, 222.0 unitsKetiga puluh item kembali semua. Limit adalah ukuran halaman, dan tugas paginator adalah terus meminta sampai halamannya habis, jadi keduanya saling meniadakan dengan tepat. AWS mendefinisikannya sebagai "the maximum number of items to evaluate (not necessarily the number of matching items)" (diambil 2026-07-28). Kalau Anda mau lima item pertama, break sendiri dari loop-nya setelah halaman pertama.
Halaman kecil berbiaya sedikit lebih mahal, bukan lebih murah. Partisi yang sama, dibaca tanpa Limit, dipaginasi dalam dua halaman seharga 220,0 unit; pada Limit: 5 ia butuh tujuh panggilan seharga 222,0. Setiap halaman membulatkan total byte-nya sendiri ke batas 4 KB berikutnya, jadi lebih banyak halaman berarti lebih banyak pembulatan, plus enam perjalanan bolak-balik tambahan berupa latensi. Menurunkan Limit supaya "membaca lebih sedikit" tidak memberi Anda keduanya.
Loop-nya selalu melakukan satu panggilan lebih banyak daripada datanya. Halaman 7 di atas mengembalikan nol item. DynamoDB menyerahkan sebuah LastEvaluatedKey setiap kali Limit tercapai, terlepas apakah masih ada lanjutannya, dan HasMorePages() memercayainya. Jadi paginator ber-Limit berakhir pada satu request yang terbuang, dan efek samping per halaman apa pun (progress bar, flush batch, satu baris log) sekali terpicu pada halaman kosong. Beri penjagaan pada len(page.Items).
HasMorePages() bernilai true sebelum request pertama. Ia diinisialisasi ke true supaya loop for-nya masuk sama sekali, artinya ia sebuah kondisi loop, bukan pemeriksaan "ada data". Memanggilnya untuk memutuskan apakah perlu repot-repot melakukan query selalu menjawab ya.
Error muncul per halaman, dan pembacaan parsial adalah keadaan yang nyata. NextPage mengembalikan smithy error terbungkus yang sama seperti panggilan lain, jadi buka bungkusnya dengan errors.As terhadap *types.ProvisionedThroughputExceededException dan kawan-kawannya alih-alih mencocokkan string. log.Fatalf pada cuplikan itu membuang halaman-halaman yang sudah terkumpul; di sebuah layanan Anda biasanya ingin menyimpan items dan melaporkan sejauh mana Anda sampai.
ScanIndexForward adalah satu-satunya cara membaca partisi secara mundur. Setel ScanIndexForward: aws.Bool(false) untuk urutan sort key menurun. Tidak ada "sort by" untuk hal lain: urutan datang dari sort key, dan kalau Anda butuh urutan lain Anda butuh index lain. IndexName: aws.String("...") memindahkan seluruh query ke index tersebut.
Dua package membuat ini lebih ringkas. github.com/aws/aws-sdk-go-v2/feature/dynamodb/expression membangun key condition dan kedua map placeholder dari expression.Key("Artist").Equal(expression.Value("Arturo Sandoval")), yang menghapus pasangan #hashKey/:hashKeyValue tulisan tangan berikut risiko reserved word yang menyertainya. attributevalue.UnmarshalListOfMaps(page.Items, &songs) mengubah satu halaman langsung menjadi []Song.
Lakukan secara visual
Dua map placeholder itu adalah bagian yang layak dihasilkan alih-alih diketik. DynamoDB Expression Builder gratis merakit key condition beserta ExpressionAttributeNames dan ExpressionAttributeValues yang cocok lalu memancarkan literal Go-nya, sehingga nama dan nilainya tidak bisa menyimpang satu sama lain.
Untuk menjalankan query pada tabel Anda sendiri — form key-condition, grid yang memaginasi sambil Anda menggulir, salin request-nya kembali sebagai kode Go — unduh DynoTable.
Contoh terkait
- DynamoDB Query di Java — query yang sama dengan AWS SDK for Java 2.x.
- DynamoDB Scan di Go — ketika Anda tidak bisa masuk ke sebuah partisi lewat key.
- Paginasi —
LastEvaluatedKey,ExclusiveStartKey, dan mengapaLimitbukan ukuran halaman. - "Query condition missed key schema element" — key condition menyebut atribut yang salah atau melewatkan partition key.
- "Query key condition not supported" — operator yang tidak bisa dipakai key condition, seperti contains atau kondisi sort key kedua.
Referensi
- Query — Amazon DynamoDB API Reference
- Use Query with an AWS SDK or CLI — Amazon DynamoDB Developer Guide
- dynamodb package — AWS SDK for Go v2 (pkg.go.dev)
- expression package — AWS SDK for Go v2 (pkg.go.dev)
- Querying tables — Amazon DynamoDB Developer Guide
Diukur 2026-07-28 pada go1.26.5 dengan aws-sdk-go-v2/service/dynamodb v1.62.1, terhadap DynamoDB Local (amazon/dynamodb-local) pada port 9000, atas sebuah partisi berisi 30 item berukuran ~60 KB masing-masing. Hitungan per halaman dan pembacaan kapasitasnya adalah keluaran yang ditangkap apa adanya. DynamoDB Local menerapkan aturan pembulatan yang terdokumentasi; anggap unit absolutnya sebagai peragaan bentuknya saja dan ukur layanan sungguhannya sebelum menakar kapasitas.