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 units

Otuz öğ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

Kaynaklar

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.

Bu isteği görsel olarak oluştur

Bu operasyonu ücretsiz DynamoDB Sorgu Oluşturucuda kur — anahtar koşulu, filtre, index, Limit, sıralama yönü ve bir sayfalama döngüsü — ve çalıştırılabilir bir SDK v3, CLI veya boto3 programı olarak geri kopyala.

DynamoDB Sorgu Oluşturucuyu aç

Console olmadan DynamoDB ile çalış

DynamoDB’nin çalıştıramadığı gerçek SQL’i çalıştıran hızlı bir DynamoDB masaüstü istemcisi — JOINs, GROUP BY, toplamalar — görsel düzenleme ve kendi Bedrock anahtarların üzerinde bir yapay zekâ aracısıyla.

30 günlük ücretsiz deneme, kredi kartı yok — ardından süre sınırı olmayan Ücretsiz plan.