Scansione di tabelle e indici: Java - Amazon DynamoDB

Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.

Scansione di tabelle e indici: Java

L'operazione Scan legge tutti gli elementi in una tabella o indice in Amazon DynamoDB.

Di seguito sono riportati i passaggi per scansionare una tabella utilizzando il documento. AWS SDK for Java API

  1. Creare un'istanza della classe AmazonDynamoDB.

  2. Crea un'istanza della classe ScanRequest e specifica i parametri dell'operazione di scansione.

    L'unico parametro richiesto è il nome della tabella.

  3. Eseguire il metodo scan e fornire l'oggetto ScanRequest creato nella fase precedente.

La seguente tabella Reply archivia le risposte per i thread del forum.

Esempio
Reply ( Id, ReplyDateTime, Message, PostedBy )

La tabella mantiene tutte le risposte per i vari thread del forum. Di conseguenza, la chiave primaria è costituita sia da Id (chiave di partizione) sia da ReplyDateTime (chiave di ordinamento). Il seguente esempio di codice Java analizza l'intera tabella. L'istanza ScanRequest specifica il nome della tabella da sottoporre a scansione.

Esempio
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); }

Specifica dei parametri facoltativi

Il metodo scan supporta diversi parametri facoltativi. Ad esempio, se lo desideri, puoi utilizzare un'espressione filtro per filtrare il risultato della scansione. In un'espressione filtro è possibile specificare nomi e valori di una condizione e attributi per i quali si desidera valutare la condizione. Per ulteriori informazioni, consulta Scan.

Il seguente esempio Java esegue la scansione della tabella ProductCatalog per trovare gli articoli con un prezzo inferiore a 0. L'esempio specifica i parametri facoltativi seguenti:

  • Un'espressione di filtro per recuperare solo gli articoli con un prezzo inferiore a 0 (condizione di errore).

  • Un elenco di attributi da recuperare per gli elementi nei risultati della query.

Esempio
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); }

Se si desidera, è possibile limitare la dimensione della pagina o il numero di elementi per pagina utilizzando il metodo withLimit della richiesta di scansione. Ogni volta che viene eseguito il metodo scan, si ottiene una pagina di risultati contenente il numero specificato di elementi. Per recuperare la pagina successiva, è necessario eseguire di nuovo il metodo scan fornendo il valore della chiave primaria dell'ultimo elemento nella pagina precedente, in modo che il metodo scan possa restituire il set successivo di elementi. Fornire queste informazioni nella richiesta utilizzando il metodo withExclusiveStartKey. Inizialmente, il parametro di questo metodo può essere nullo. Per recuperare le pagine successive, devi aggiornare questo valore di proprietà alla chiave primaria dell'ultimo item nella pagina precedente.

Il seguente esempio di codice Java esegue la scansione della tabella ProductCatalog. Nella richiesta, vengono utilizzati i metodi withLimit e withExclusiveStartKey. Il ciclo do/while continua a eseguire la scansione di una pagina alla volta finché il metodo getLastEvaluatedKey non restituisce un valore null.

Esempio
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);

Esempio: scansione tramite Java

Nel seguente esempio Java viene eseguita la scansione della tabella ProductCatalog per trovare gli articoli con un prezzo inferiore a 100.

Nota

The SDK for Java fornisce anche un modello di persistenza degli oggetti, che consente di mappare le classi lato client alle tabelle DynamoDB. Questo approccio può ridurre la quantità di codice da scrivere. Per ulteriori informazioni, consulta Java 1.x: D ynamoDBMapper.

Nota

In questo esempio di codice si presuppone che i dati siano già stati caricati in DynamoDB per l'account seguendo le istruzioni riportate nella sezione Creazione di tabelle e caricamento di dati per esempi di codice in DynamoDB.

Per step-by-step istruzioni su come eseguire l'esempio seguente, consulta. Esempi di codice Java

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()); } } }

Esempio: scansione parallela tramite Java

Il seguente esempio di codice Java riporta una scansione parallela. Il programma elimina e crea nuovamente una tabella denominata ParallelScanTest, quindi carica la tabella con i dati. Una volta terminato il caricamento dei dati, il programma genera più thread ed emette richieste Scanin parallelo. Il programma stampa le statistiche di runtime per ogni richiesta parallela.

Nota

The SDK for Java fornisce anche un modello di persistenza degli oggetti, che consente di mappare le classi lato client alle tabelle DynamoDB. Questo approccio può ridurre la quantità di codice da scrivere. Per ulteriori informazioni, consulta Java 1.x: D ynamoDBMapper.

Nota

In questo esempio di codice si presuppone che i dati siano già stati caricati in DynamoDB per l'account seguendo le istruzioni riportate nella sezione Creazione di tabelle e caricamento di dati per esempi di codice in DynamoDB.

Per step-by-step istruzioni su come eseguire l'esempio seguente, consulta. Esempi di codice Java

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(); } } }