Go'da DynamoDB Query (AWS SDK v2)
Query tek bir bölümü okur, isteğe bağlı olarak sıralama anahtarıyla daraltılmış (Query ile Scan bunun ne zaman doğru tercih olduğunu, anahtar koşul ifadeleri ise her geçerli operatörü anlatır). AWS SDK for Go v2'nin eklediği şey QueryPaginator'dır; o da LastEvaluatedKey döngüsünü bir for döngüsüne çevirir ve bunu yaparken durma şansınızı sessizce elinizden alır.
Kod
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))
}Açıklama
Limit, sayfalayıcının ne okuduğunu sınırlamaz. Paraya mal olan da budur. Yukarıdaki girdiye Limit: aws.Int32(5) koyup her biri ~60 KB olan 30 öğelik bir bölüm üzerinde çalıştırmak şunu üretti:
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 unitsOtuz öğenin hepsi geri geldi. Limit bir sayfa boyutudur ve sayfalayıcının işi sayfalar tükenene kadar istemeye devam etmektir; dolayısıyla ikisi birbirini tam olarak götürür. AWS onu "the maximum number of items to evaluate (not necessarily the number of matching items)" diye tanımlar (2026-07-28 tarihinde alındı). İlk beş öğeyi istiyorsanız ilk sayfadan sonra döngüden kendiniz break edin.
Küçük sayfalar biraz daha pahalıdır, daha ucuz değil. Aynı bölüm Limit olmadan okunduğunda iki sayfada 220,0 birime sayfalanır; Limit: 5 ile yedi çağrı ve 222,0 birim aldı. Her sayfa kendi bayt toplamını bir sonraki 4 KB sınırına yuvarlar; yani daha çok sayfa daha çok yuvarlama, artı altı fazladan gidiş dönüş gecikmesi demektir. "Daha az okumak" için Limit'i düşürmek size ikisini de vermez.
Döngü her zaman veri olduğundan bir fazla çağrı yapar. Yukarıdaki 7. sayfa sıfır öğe döndürdü. DynamoDB, Limit'e ulaşıldığında ardından bir şey gelip gelmediğine bakmaksızın bir LastEvaluatedKey geri verir ve HasMorePages() buna inanır. Dolayısıyla Limit'li bir sayfalayıcı boşa giden bir istekle biter ve sayfa başına her yan etki (ilerleme çubuğu, toplu boşaltma, günlük satırı) boş bir sayfaya karşı bir kez tetiklenir. len(page.Items) üzerinde koruma koyun.
HasMorePages() ilk istekten önce true'dur. for döngüsünün hiç girebilmesi için true'ya ilklenir; yani bir "veri var mı" denetimi değil, bir döngü koşuludur. Sorgu yapmaya değip değmeyeceğine karar vermek için çağırmak her zaman evet der.
Hatalar sayfa başına yüzeye çıkar ve kısmi bir okuma gerçek bir durumdur. NextPage, başka her çağrıyla aynı sarmalanmış smithy hatasını döndürür; dolayısıyla string eşleştirmek yerine *types.ProvisionedThroughputExceededException ve arkadaşlarına karşı errors.As ile açın. Bloğun log.Fatalf'ı, o ana kadar toplanan sayfaları çöpe atar; bir serviste genellikle items'ı tutmak ve nereye kadar geldiğinizi bildirmek istersiniz.
ScanIndexForward, bir bölümü tersten okumanın tek yoludur. Azalan sıralama anahtarı sırası için ScanIndexForward: aws.Bool(false) verin. Başka hiçbir şey için "şuna göre sırala" yoktur: sıra sıralama anahtarından gelir ve başka bir sıra gerekiyorsa başka bir indeks gerekir. IndexName: aws.String("...") sorgunun tamamını o indekse taşır.
İki paket bunu kısaltır. github.com/aws/aws-sdk-go-v2/feature/dynamodb/expression, anahtar koşulunu ve iki yer tutucu haritasını expression.Key("Artist").Equal(expression.Value("Arturo Sandoval")) ifadesinden kurar; bu da elle yazılan #hashKey/:hashKeyValue çiftlerini ve onlarla birlikte ayrılmış sözcük riskini ortadan kaldırır. attributevalue.UnmarshalListOfMaps(page.Items, &songs) ise bir sayfayı doğrudan []Song'a çevirir.
Görsel olarak yapın
İki yer tutucu haritası, yazmak yerine üretilmeye değer kısımdır. Ücretsiz DynamoDB Expression Builder anahtar koşulunu eşleşen ExpressionAttributeNames ve ExpressionAttributeValues ile bir araya getirir ve Go değişmezini verir; böylece adlar ile değerler birbirinden ayrı düşemez.
Kendi tablolarınıza karşı sorgu çalıştırmak — anahtar koşulu formu, kaydırdıkça sayfalanan bir ızgara, isteği Go olarak geri kopyalama — için DynoTable'ı indirin.
İlgili örnekler
- Java'da DynamoDB Query — AWS SDK for Java 2.x ile aynı sorgu.
- Go'da DynamoDB Scan — bir bölüme anahtarla giremediğinizde.
- Sayfalama —
LastEvaluatedKey,ExclusiveStartKeyveLimitneden bir sayfa boyutu değildir. - "Query condition missed key schema element" — anahtar koşulu yanlış özniteliği adlandırıyor ya da bölüm anahtarını atlıyor.
- "Query key condition not supported" — anahtar koşulunun kullanamayacağı bir operatör, contains ya da ikinci bir sıralama anahtarı koşulu gibi.
Kaynaklar
- 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
2026-07-28 tarihinde go1.26.5 üzerinde aws-sdk-go-v2/service/dynamodb v1.62.1 ile, 9000 numaralı porttaki DynamoDB Local'a (amazon/dynamodb-local) karşı, her biri ~60 KB olan 30 öğelik bir bölüm üzerinde ölçüldü. Sayfa başına sayımlar ve kapasite okumaları birebir alınmıştır. DynamoDB Local belgelenmiş yuvarlama kurallarını uygular; mutlak birimleri biçimin bir gösterimi sayın ve boyutlandırmadan önce hizmeti ölçün.