DynamoDB Scan di Go (AWS SDK v2)
NewScanPaginator adalah kursor, bukan koleksi: ia mulai dengan optimistis, berakhir kehabisan, dan mengambil ukuran halamannya dari tempat yang tidak diperlihatkan ScanInput di hadapan Anda. Untuk menghindari Scan sama sekali, lihat Query vs. Scan.
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.NewScanPaginator(client, &dynamodb.ScanInput{
TableName: aws.String("Music"),
FilterExpression: aws.String("#filter0 >= :filterValue0"),
ExpressionAttributeNames: map[string]string{
"#filter0": "Year",
},
ExpressionAttributeValues: map[string]types.AttributeValue{
":filterValue0": &types.AttributeValueMemberN{Value: "2010"},
},
})
var items []map[string]types.AttributeValue
for paginator.HasMorePages() {
page, err := paginator.NextPage(ctx)
if err != nil {
log.Fatalf("scan: %v", err)
}
items = append(items, page.Items...)
}
fmt.Printf("Matched %d items\n", len(items))
}Apa yang sebenarnya dikembalikan HasMorePages()
Terhadap fixture 600 lagu berukuran sekitar 3,9 KB per item, yang 8 di antaranya cocok dengan Year >= 2010 dan berada di urutan terakhir:
fresh HasMorePages(): true (before any request)
page 1: len(page.Items)=0 ScannedCount=271 CU=128.5 LastEvaluatedKey set
page 2: len(page.Items)=0 ScannedCount=271 CU=128.5 LastEvaluatedKey set
page 3: len(page.Items)=8 ScannedCount= 58 CU= 27.5 LastEvaluatedKey nil
exhausted HasMorePages(): false
NextPage() after exhaustion: err = "no more pages available"HasMorePages() bernilai true sebelum panggilan pertama, jadi loop-nya selalu berjalan setidaknya sekali. Anda tidak bisa memakainya untuk menguji apakah sebuah tabel kosong. Dua halaman lalu mengembalikan nol item sementara scan-nya masih berjalan, artinya if len(page.Items) == 0 { break } melaporkan hasil kosong pada tabel yang menyimpan 8 kecocokan. Dan paginator-nya sekali pakai: setelah loop, nilainya habis, dan NextPage mengembalikan error alih-alih memulai ulang. Melakukan scan lagi berarti memanggil NewScanPaginator lagi.
Limit ada di dua tempat, dan option-lah yang menang
Go membagi ukuran halaman antara struct input dan option milik paginator sendiri. Setel keduanya dan option yang diutamakan:
ScanInput.Limit = 500, ScanPaginatorOptions.Limit = 25 -> ScannedCount 25Menugaskan in.Limit = aws.Int32(500) lalu berharap halaman berisi 500 item adalah kekeliruan yang tak bersuara ketika sebuah functional option di tempat lain sudah menyetel 25. Kalau Anda hanya menyentuh ScanInput, paginator menghormatinya.
Diukur 2026-07-28 terhadap DynamoDB Local (amazon/dynamodb-local) dengan aws-sdk-go-v2/service/dynamodb v1.62.1 pada go1.26.5.
Penjelasan
page.Itemsbertipe[]map[string]types.AttributeValue, bukan struct Anda.attributevalue.UnmarshalListOfMaps(items, &songs)mengonversi seluruh batch dalam satu panggilan dan mengubahYearmenjadiintGo; tag structdynamodbavyang mengendalikan pemetaannya.- Angka adalah string di jalur transport. Nilai mentahnya adalah
&types.AttributeValueMemberN{Value: "2010"}— anggotaNmenyimpanstringGo, jadistrconvberdiri di kedua sisi aritmetika apa pun kecuali Anda meng-unmarshal ke struct bertipe. FilterExpressionberjalan setelah pembacaan, dan itulah sebabnya dua halaman kosong itu tetap menghabiskan 128,5 unit masing-masing. Referensi API menyatakan dengan tegas bahwa pemfilteran "does not consume any additional read capacity units", dan konsekuensinya adalah ia juga tidak menghemat apa pun.#filter0itu wajib, bukan gaya-gayaan.Yearadalah reserved word DynamoDB; tanpa alias ia mengembalikanValidationException: Invalid FilterExpression: Attribute name is a reserved keyword; reserved keyword: Year.Segment/TotalSegmentsmemberi tiap goroutine irisan tabelnya sendiri, dan masing-masing butuh paginator sendiri. Paralelisme memangkas wall clock dan menghabiskan kapasitas yang sama.
Lakukan secara visual
Query builder DynamoDB memancarkan bentuk program utuhnya — filter, map nama dan nilai, serta loop paginator — sehingga bagian yang diukur halaman ini dihasilkan, bukan diingat-ingat.
Untuk melihat berapa banyak item yang benar-benar disentuh sebuah filter sebelum Anda menjalankan scan-nya di layanan, unduh DynoTable dan jalankan terhadap tabelnya dalam sebuah grid.
Contoh terkait
- DynamoDB Scan di Java — scan yang sama dengan AWS SDK for Java 2.x.
- DynamoDB Query di Go — pembacaan yang lebih murah yang biasanya harus Anda pilih.
- Query vs. Scan — kapan (jarang) sebuah
Scanbisa dibenarkan. - Mengapa Scan DynamoDB saya lambat dan mahal? — model biayanya dan cara menghindarinya.
- DynamoDB ProvisionedThroughputExceededException — apa yang dilakukan scan seluruh tabel terhadap kapasitas tabel provisioned.
- DynamoDB ThrottlingException — throttle yang satunya, dan bagaimana exponential backoff menanganinya.