Scannen von Tabellen und Indizes: Java - Amazon DynamoDB

Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.

Scannen von Tabellen und Indizes: Java

Die Scan-Operation liest alle Elemente einer Tabelle oder eines Indexes in Amazon DynamoDB.

Im Folgenden finden Sie die Schritte zum Scannen einer Tabelle mit der - AWS SDK for Java Dokument-API.

  1. Erstellen Sie eine Instance der AmazonDynamoDB-Klasse.

  2. Erstellen Sie eine Instance der ScanRequest-Klasse und stellen Sie Scan-Parameter bereit.

    Der einzige erforderliche Parameter ist der Tabellenname.

  3. Führen Sie die scan-Methode aus und stellen Sie das ScanRequest-Objekt bereit, das Sie im vorherigen Schritt erstellt haben.

Die folgende Reply-Tabelle speichert Antworten für Forum-Threads.

Beispiel
Reply ( Id, ReplyDateTime, Message, PostedBy )

Die Tabelle enthält alle Antworten zu verschiedenen Forum-Threads. Daher besteht der Primärschlüssel aus Id (Partitionsschlüssel) und ReplyDateTime (Sortierschlüssel). Der folgende Java-Codebeispiel scannt die gesamte Tabelle. Die ScanRequest-Instance gibt den Namen der zu scannenden Tabelle an.

Beispiel
AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard().build(); ScanRequest scanRequest = new ScanRequest() .withTableName("Reply"); ScanResponse result = client.scan(scanRequest); for (Map<String, AttributeValue> item : result.getItems()){ printItem(item); }

Angeben eines optionalen Parameters

Die scan-Methode unterstützt mehrere optionale Parameter. Beispielsweise können Sie optional einen Filterausdruck verwenden, um die Scan-Ergebnisse zu filtern. In einem Filterausdruck können Sie eine Bedingung, Attributnamen und Werte angeben, für die Sie die Bedingung ausgewertet haben möchten. Weitere Informationen finden Sie unter Scan.

Der folgende Java-Beispiel scannt die ProductCatalog-Tabelle, um Elemente zu finden, deren Preis kleiner als 0 ist. Das Beispiel gibt die folgenden optionalen Parameter an:

  • Ein Filterausdruck, um nur die Elemente abzurufen, deren Preis kleiner als 0 ist (Fehlerbedingung).

  • Eine Liste von Attributen, die für Elemente in den Abfrageergebnissen abgerufen wird.

Beispiel
Map<String, AttributeValue> expressionAttributeValues = new HashMap<String, AttributeValue>(); expressionAttributeValues.put(":val", new AttributeValue().withN("0")); ScanRequest scanRequest = new ScanRequest() .withTableName("ProductCatalog") .withFilterExpression("Price < :val") .withProjectionExpression("Id") .withExpressionAttributeValues(expressionAttributeValues); ScanResponse result = client.scan(scanRequest); for (Map<String, AttributeValue> item : result.getItems()) { printItem(item); }

Optional können Sie auch die Seitengröße oder die Anzahl von Elementen pro Seite begrenzen, indem Sie die withLimit-Methode der Scan-Anforderung verwenden. Bei jeder Ausführung der scan-Methode erhalten Sie eine Ergebnisseite, die über die angegebene Anzahl von Elementen verfügt. Um die nächste Seite abzurufen, führen Sie die scan-Methode erneut aus, indem Sie den Primärschlüsselwert des letzten Elements auf der vorherigen Seite angeben, damit die scan-Methode den nächsten Elementsatz zurückgeben kann. Sie stellen diese Informationen in der Anforderung bereit, indem Sie die withExclusiveStartKey-Methode verwenden. Zu Beginn kann der Parameter dieser Methode Null sein. Zum Abrufen von Folgeseiten müssen Sie diesen Eigenschaftswert für den Primärschlüssel des letzten Elements in der vorangegangenen Seite aktualisieren.

Im folgenden Java-Codebeispiel wird die ProductCatalog-Tabelle gescannt. In der Anforderung werden die withLimit und withExclusiveStartKey-Methoden verwendet. Die do/while-Schleife scannt weiterhin eine Seite nach der anderen, bis die getLastEvaluatedKey-Methode des Ergebnisses den Wert Null zurückgibt.

Beispiel
Map<String, AttributeValue> lastKeyEvaluated = null; do { ScanRequest scanRequest = new ScanRequest() .withTableName("ProductCatalog") .withLimit(10) .withExclusiveStartKey(lastKeyEvaluated); ScanResponse result = client.scan(scanRequest); for (Map<String, AttributeValue> item : result.getItems()){ printItem(item); } lastKeyEvaluated = result.getLastEvaluatedKey(); } while (lastKeyEvaluated != null);

Beispiel – Scannen mit Java

Das folgende Java-Codebeispiel bietet ein Arbeitsbeispiel, das die ProductCatalog-Tabelle scannt, um Elemente zu finden, deren Preis unter 100 liegt.

Anmerkung

SDK für Java stellt zudem ein Objekt-Persistenzmodell bereit, mit dem Sie den DynamoDB-Tabellen clientseitige Klassen zuordnen können. Mit diesem Ansatz können Sie die Codemenge, die Sie schreiben müssen, verringern. Weitere Informationen finden Sie unter Java 1.x: DynamoDBMapper.

Anmerkung

In diesem Codebeispiel wird davon ausgegangen, dass Sie bereits Daten für Ihr Konto in DynamoDB geladen haben, indem Sie die Anweisungen im Erstellen von Tabellen und Laden von Daten für Codebeispiele in DynamoDB-Abschnitt befolgen.

step-by-step Anweisungen zum Ausführen des folgenden Beispiels finden Sie unter Java-Codebeispiele.

package com.amazonaws.codesamples.document; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import com.amazonaws.services.dynamodbv2.AmazonDynamoDB; import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientBuilder; import com.amazonaws.services.dynamodbv2.document.DynamoDB; import com.amazonaws.services.dynamodbv2.document.Item; import com.amazonaws.services.dynamodbv2.document.ItemCollection; import com.amazonaws.services.dynamodbv2.document.ScanOutcome; import com.amazonaws.services.dynamodbv2.document.Table; public class DocumentAPIScan { static AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard().build(); static DynamoDB dynamoDB = new DynamoDB(client); static String tableName = "ProductCatalog"; public static void main(String[] args) throws Exception { findProductsForPriceLessThanOneHundred(); } private static void findProductsForPriceLessThanOneHundred() { Table table = dynamoDB.getTable(tableName); Map<String, Object> expressionAttributeValues = new HashMap<String, Object>(); expressionAttributeValues.put(":pr", 100); ItemCollection<ScanOutcome> items = table.scan("Price < :pr", // FilterExpression "Id, Title, ProductCategory, Price", // ProjectionExpression null, // ExpressionAttributeNames - not used in this example expressionAttributeValues); System.out.println("Scan of " + tableName + " for items with a price less than 100."); Iterator<Item> iterator = items.iterator(); while (iterator.hasNext()) { System.out.println(iterator.next().toJSONPretty()); } } }

Beispiel – Paralleles Scannen mit Java

Das folgende Java-Codebeispiel zeigt einen parallelen Scan. Das Programm löscht und erstellt erneut die Tabelle mit dem Namen ParallelScanTest und lädt dann die Tabelle mit Daten. Wenn der Ladevorgang abgeschlossen ist, erzeugt das Programm mehrere Threads und gibt parallele Scan-Anforderungen aus. Das Programm gibt Laufzeitstatistiken für jede parallele Anforderung aus.

Anmerkung

Das SDK für Java stellt auch ein Objektpersistenzmodell bereit, mit dem Sie Ihre clientseitigen Klassen DynamoDB-Tabellen zuordnen können. Mit diesem Ansatz können Sie die Codemenge, die Sie schreiben müssen, verringern. Weitere Informationen finden Sie unter Java 1.x: DynamoDBMapper.

Anmerkung

In diesem Codebeispiel wird davon ausgegangen, dass Sie bereits Daten für Ihr Konto in DynamoDB geladen haben, indem Sie die Anweisungen im Erstellen von Tabellen und Laden von Daten für Codebeispiele in DynamoDB-Abschnitt befolgen.

step-by-step Anweisungen zum Ausführen des folgenden Beispiels finden Sie unter Java-Codebeispiele.

package com.amazonaws.codesamples.document; import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import com.amazonaws.AmazonServiceException; import com.amazonaws.services.dynamodbv2.AmazonDynamoDB; import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientBuilder; import com.amazonaws.services.dynamodbv2.document.DynamoDB; import com.amazonaws.services.dynamodbv2.document.Item; import com.amazonaws.services.dynamodbv2.document.ItemCollection; import com.amazonaws.services.dynamodbv2.document.ScanOutcome; import com.amazonaws.services.dynamodbv2.document.Table; import com.amazonaws.services.dynamodbv2.document.spec.ScanSpec; import com.amazonaws.services.dynamodbv2.model.AttributeDefinition; import com.amazonaws.services.dynamodbv2.model.KeySchemaElement; import com.amazonaws.services.dynamodbv2.model.KeyType; import com.amazonaws.services.dynamodbv2.model.ProvisionedThroughput; public class DocumentAPIParallelScan { // total number of sample items static int scanItemCount = 300; // number of items each scan request should return static int scanItemLimit = 10; // number of logical segments for parallel scan static int parallelScanThreads = 16; // table that will be used for scanning static String parallelScanTestTableName = "ParallelScanTest"; static AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard().build(); static DynamoDB dynamoDB = new DynamoDB(client); public static void main(String[] args) throws Exception { try { // Clean up the table deleteTable(parallelScanTestTableName); createTable(parallelScanTestTableName, 10L, 5L, "Id", "N"); // Upload sample data for scan uploadSampleProducts(parallelScanTestTableName, scanItemCount); // Scan the table using multiple threads parallelScan(parallelScanTestTableName, scanItemLimit, parallelScanThreads); } catch (AmazonServiceException ase) { System.err.println(ase.getMessage()); } } private static void parallelScan(String tableName, int itemLimit, int numberOfThreads) { System.out.println( "Scanning " + tableName + " using " + numberOfThreads + " threads " + itemLimit + " items at a time"); ExecutorService executor = Executors.newFixedThreadPool(numberOfThreads); // Divide DynamoDB table into logical segments // Create one task for scanning each segment // Each thread will be scanning one segment int totalSegments = numberOfThreads; for (int segment = 0; segment < totalSegments; segment++) { // Runnable task that will only scan one segment ScanSegmentTask task = new ScanSegmentTask(tableName, itemLimit, totalSegments, segment); // Execute the task executor.execute(task); } shutDownExecutorService(executor); } // Runnable task for scanning a single segment of a DynamoDB table private static class ScanSegmentTask implements Runnable { // DynamoDB table to scan private String tableName; // number of items each scan request should return private int itemLimit; // Total number of segments // Equals to total number of threads scanning the table in parallel private int totalSegments; // Segment that will be scanned with by this task private int segment; public ScanSegmentTask(String tableName, int itemLimit, int totalSegments, int segment) { this.tableName = tableName; this.itemLimit = itemLimit; this.totalSegments = totalSegments; this.segment = segment; } @Override public void run() { System.out.println("Scanning " + tableName + " segment " + segment + " out of " + totalSegments + " segments " + itemLimit + " items at a time..."); int totalScannedItemCount = 0; Table table = dynamoDB.getTable(tableName); try { ScanSpec spec = new ScanSpec().withMaxResultSize(itemLimit).withTotalSegments(totalSegments) .withSegment(segment); ItemCollection<ScanOutcome> items = table.scan(spec); Iterator<Item> iterator = items.iterator(); Item currentItem = null; while (iterator.hasNext()) { totalScannedItemCount++; currentItem = iterator.next(); System.out.println(currentItem.toString()); } } catch (Exception e) { System.err.println(e.getMessage()); } finally { System.out.println("Scanned " + totalScannedItemCount + " items from segment " + segment + " out of " + totalSegments + " of " + tableName); } } } private static void uploadSampleProducts(String tableName, int itemCount) { System.out.println("Adding " + itemCount + " sample items to " + tableName); for (int productIndex = 0; productIndex < itemCount; productIndex++) { uploadProduct(tableName, productIndex); } } private static void uploadProduct(String tableName, int productIndex) { Table table = dynamoDB.getTable(tableName); try { System.out.println("Processing record #" + productIndex); Item item = new Item().withPrimaryKey("Id", productIndex) .withString("Title", "Book " + productIndex + " Title").withString("ISBN", "111-1111111111") .withStringSet("Authors", new HashSet<String>(Arrays.asList("Author1"))).withNumber("Price", 2) .withString("Dimensions", "8.5 x 11.0 x 0.5").withNumber("PageCount", 500) .withBoolean("InPublication", true).withString("ProductCategory", "Book"); table.putItem(item); } catch (Exception e) { System.err.println("Failed to create item " + productIndex + " in " + tableName); System.err.println(e.getMessage()); } } private static void deleteTable(String tableName) { try { Table table = dynamoDB.getTable(tableName); table.delete(); System.out.println("Waiting for " + tableName + " to be deleted...this may take a while..."); table.waitForDelete(); } catch (Exception e) { System.err.println("Failed to delete table " + tableName); e.printStackTrace(System.err); } } private static void createTable(String tableName, long readCapacityUnits, long writeCapacityUnits, String partitionKeyName, String partitionKeyType) { createTable(tableName, readCapacityUnits, writeCapacityUnits, partitionKeyName, partitionKeyType, null, null); } private static void createTable(String tableName, long readCapacityUnits, long writeCapacityUnits, String partitionKeyName, String partitionKeyType, String sortKeyName, String sortKeyType) { try { System.out.println("Creating table " + tableName); List<KeySchemaElement> keySchema = new ArrayList<KeySchemaElement>(); keySchema.add(new KeySchemaElement().withAttributeName(partitionKeyName).withKeyType(KeyType.HASH)); // Partition // key List<AttributeDefinition> attributeDefinitions = new ArrayList<AttributeDefinition>(); attributeDefinitions .add(new AttributeDefinition().withAttributeName(partitionKeyName) .withAttributeType(partitionKeyType)); if (sortKeyName != null) { keySchema.add(new KeySchemaElement().withAttributeName(sortKeyName).withKeyType(KeyType.RANGE)); // Sort // key attributeDefinitions .add(new AttributeDefinition().withAttributeName(sortKeyName).withAttributeType(sortKeyType)); } Table table = dynamoDB.createTable(tableName, keySchema, attributeDefinitions, new ProvisionedThroughput() .withReadCapacityUnits(readCapacityUnits).withWriteCapacityUnits(writeCapacityUnits)); System.out.println("Waiting for " + tableName + " to be created...this may take a while..."); table.waitForActive(); } catch (Exception e) { System.err.println("Failed to create table " + tableName); e.printStackTrace(System.err); } } private static void shutDownExecutorService(ExecutorService executor) { executor.shutdown(); try { if (!executor.awaitTermination(10, TimeUnit.SECONDS)) { executor.shutdownNow(); } } catch (InterruptedException e) { executor.shutdownNow(); // Preserve interrupt status Thread.currentThread().interrupt(); } } }