Java (AWS SDK v2) ile DynamoDB Scan

scanPaginator, LastEvaluatedKey'i sizin yerinize halleder ve çoğu kişinin bir sonraki adımda uzandığı tek düğme — .limit(...) — aynı taramayı daha yavaş ve biraz daha pahalı hâle getirir. Scan'den bütünüyle ne zaman kaçınmanız gerektiği için bkz. Query ile Scan karşılaştırması.

Kod

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
import software.amazon.awssdk.services.dynamodb.model.AttributeValue;
import software.amazon.awssdk.services.dynamodb.model.DynamoDbException;
import software.amazon.awssdk.services.dynamodb.model.ScanRequest;
import software.amazon.awssdk.services.dynamodb.model.ScanResponse;

public class ScanExample {
    public static void main(String[] args) {
        try (DynamoDbClient ddb = DynamoDbClient.builder()
                .region(Region.US_EAST_1)
                .build()) {

            Map<String, String> names = new HashMap<>();
            names.put("#filter0", "Year");

            Map<String, AttributeValue> values = new HashMap<>();
            values.put(":filterValue0", AttributeValue.builder().n("2010").build());

            ScanRequest request = ScanRequest.builder()
                    .tableName("Music")
                    .filterExpression("#filter0 >= :filterValue0")
                    .expressionAttributeNames(names)
                    .expressionAttributeValues(values)
                    .build();

            List<Map<String, AttributeValue>> items = new ArrayList<>();
            for (ScanResponse page : ddb.scanPaginator(request)) {
                items.addAll(page.items());
            }
            System.out.println("Matched " + items.size() + " items");
        } catch (DynamoDbException e) {
            System.err.println(e.getMessage());
        }
    }
}

.limit(25) 3 isteği 25'e çevirir ve daha pahalıya mal olur

Düzenek, her biri kabaca 3,9 KB olan 600 şarkı tutuyor ve bunların 8'i eşleşiyor. Örneği yazıldığı gibi çalıştırın, sonra .limit(25) ile yeniden çalıştırın:

İstek biçimiGidiş-dönüşOkuma birimiDöndürülen öğe
yazıldığı gibi3284,58
.limit(25)25288,08

Kapasite sayfa başına, 4 KB sınırına yukarı yuvarlanarak faturalandırılır; dolayısıyla 1 MB'lık tek bir okumayı 24 küçük okumaya bölmek yuvarlamayı 24 kez öder. 25. istek diğer sürprizdir: 24. sayfa tabloyu bitirdi ve yine de bir LastEvaluatedKey döndürdü, dolayısıyla sayfalayıcı bir kez daha sordu ve scannedCount=0 aldı. DynamoDB "başka veri yok" sinyalini kısa bir sayfa döndürerek değil, o anahtarı atlayarak verir ve bir Limit sınırında bunu henüz bilmez.

.limit(...), canlı bir tabloyu kısıtlamasını istemediğiniz bir arka plan işi için bir kapasite yumuşatma düğmesidir. Bir taramayı ucuzlatmanın ya da kısaltmanın yolu değildir.

Takma ad biçimsel değildir

#filter0'ı bırakıp doğrudan Year üzerinde filtreleyin; SDK bunu awsErrorDetails() üzerinden yüzeye çıkarır:

DynamoDbException / ValidationException /
Invalid FilterExpression: Attribute name is a reserved keyword; reserved keyword: Year
/ http 400

Year, 573 ayrılmış sözcükten biridir. Bu SDK'daki her sayfalayıcı hatası gibi o da scanPaginator(request) çağırdığınızda değil, for döngüsünün ilk yinelemesinde gelir; dolayısıyla try'ın döngüyü sarması gerekir.

2026-07-28 tarihinde OpenJDK 26.0.1 üzerinde software.amazon.awssdk:dynamodb 2.49.4 ile DynamoDB Local'a (amazon/dynamodb-local) karşı ölçüldü.

Açıklama

  • İlk iki sayfa sıfır öğe döndürür. Bu filtreyle sayfa başına sonuçlar 0, 0 ve 8'dir; sırasıyla 128,5, 128,5 ve 27,5 okuma birimiyle. filterExpression okumadan sonra çalışır, dolayısıyla o iki boş yanıt tam fiyata mal olur ve herhangi bir if (page.items().isEmpty()) break, boş bir tablo bildirir.
  • ddb.scanPaginator(request).items(), sayfaları tek bir Iterable<Map<String, AttributeValue>> içinde düzleştirir ve arkanızda sayfalar; yalnızca öğeleri istediğinizde iç içe döngüyü ortadan kaldırır. Bir SdkIterable'dır, dolayısıyla .stream() çalışır — .items().stream().count() burada 8 döndürür.
  • ScanIterable her yinelemede taramayı yeniden çalıştırır. Tembeldir, önbelleklenmiş değil: aynı nesne üzerinde iki kez dönmek istekleri iki kez gönderir ve iki kez faturalandırır. Örneğin yaptığı gibi onu bir kez bir List'e boşaltın.
  • Oluşturucuda sayılar String'dir. AttributeValue.builder().n("2010") bir java.lang.String alır, çünkü DynamoDB sayıları ondalık metin olarak taşır. Bir int geçirmek derlenmez.
  • .segment(...) / .totalSegments(...), tam tablo taramasını her biri kendi sayfalayıcısına sahip işçilere böler. Bu, duvar saati süresini böler ve aynı kapasiteyi harcar.

Görsel olarak yapın

Ayrılmış sözcük denetleyicisi öznitelik adlarınızı tam AWS listesine karşı çalıştırır ve size ExpressionAttributeNames haritasını verir; bu, Year, Name, Size ve Status'ün hepsinin alınmış olduğunu her seferinde bir ValidationException ile öğrenmekten hızlıdır.

Bir filtreyi bir ScanRequest içine kablolamadan önce gerçek bir tabloya karşı denemek için DynoTable'ı indirin ve sonuçları bir ızgarada sayfalayın.

İlgili örnekler

Kaynaklar

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.