Analyse des tables et index : Java - Amazon DynamoDB

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

Analyse des tables et index : Java

L'opération Scan lit tous les éléments d'une table ou d'un index dans Amazon DynamoDB.

Voici les étapes à suivre pour numériser un tableau à l'aide du AWS SDK for Java documentAPI.

  1. Créez une instance de la classe AmazonDynamoDB.

  2. Créez une instance de la classe ScanRequest et fournissez un paramètre d'analyse.

    Le seul paramètre requis est le nom de la table.

  3. Exécutez la méthode scan et fournissez l'objet ScanRequest que vous avez créé à l'étape précédente.

La table Reply suivante stocke les réponses pour des unités d'exécution de forum.

Exemple
Reply ( Id, ReplyDateTime, Message, PostedBy )

La table conserve toutes les réponses pour différentes unités d'exécution de forum. Par conséquent, la clé primaire est composée de Id (clé de partition) et de ReplyDateTime (clé de tri). L'exemple de code Java suivant analyse la table entière. L'instance ScanRequest spécifie le nom de la table à analyser.

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

Spécification de paramètres facultatifs

La méthode scan prend en charge plusieurs paramètres facultatifs. Par exemple, vous pouvez utiliser une expression de filtre pour filtrer le résultat de l'analyse. Dans une expression de filtre, vous pouvez spécifier une condition, ainsi que des noms et valeurs d'attribut sur lesquels vous souhaitez évaluer la condition. Pour plus d'informations, consultez Scan.

L'exemple de code Java suivant analyse la table ProductCatalog pour trouver les éléments dont le prix est inférieur à 0. L'échantillon spécifie les paramètres facultatifs suivants :

  • Une expression de filtre pour extraire uniquement les éléments dont le prix est inférieur à 0 (condition d'erreur).

  • Une liste d'attributs à extraire pour les éléments figurant dans les résultats de la requête.

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

Vous pouvez également limiter la taille de page ou le nombre d'éléments par page en utilisant la méthode withLimit de la demande d'analyse. Chaque fois que vous exécutez la méthode scan, vous obtenez une page de résultats avec le nombre d'éléments spécifié. Pour extraire la page suivante, vous exécutez à nouveau la méthode scan en fournissant la valeur de clé primaire du dernier élément de la page précédente afin que la méthode scan puisse renvoyer l'ensemble d'éléments suivant. Vous fournissez ces informations dans la demande à l'aide de la méthode withExclusiveStartKey. Initialement, le paramètre de cette méthode peut être null. Pour récupérer les pages suivantes, vous devez mettre à jour cette valeur de propriété avec la clé primaire du dernier élément de la page précédente.

L'exemple de code Java suivant analyse la table ProductCatalog. Dans la requête, les méthodes withLimit et withExclusiveStartKey sont utilisées. La boucle do/while continue d'analyser une page à la fois jusqu'à ce que la méthode getLastEvaluatedKey du résultat renvoie une valeur null.

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

Exemple – Analyse avec Java

L'exemple de code Java suivant est un exemple fonctionnel qui analyse la table ProductCatalog pour trouver les éléments dont le prix est inférieur à 100.

Note

SDKfor Java fournit également un modèle de persistance des objets, qui vous permet de mapper vos classes côté client aux tables DynamoDB. Cette approche peut réduire la quantité de code que vous avez à écrire. Pour de plus amples informations, veuillez consulter Java 1.x : D ynamoDBMapper.

Note

Cet exemple de code part du principe que vous avez déjà chargé des données dans DynamoDB pour votre compte en suivant les instructions de la section Création de tables et chargement de données pour des exemples de code dans DynamoDB.

Pour step-by-step obtenir des instructions relatives à l'exécution de l'exemple suivant, reportez-vous àExemples de code 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()); } } }

Exemple – Analyse en parallèle avec Java

L'exemple de code Java suivant montre une analyse en parallèle. Le programme supprime et recrée une table nommée ParallelScanTest, puis y charge des données. Une fois le chargement de données terminé, le programme génère plusieurs unités d'exécution et émet des demandes Scan en parallèle. Le programme affiche les statistiques d'exécution pour chaque demande en parallèle.

Note

SDKfor Java fournit également un modèle de persistance des objets, qui vous permet de mapper vos classes côté client aux tables DynamoDB. Cette approche peut réduire la quantité de code que vous avez à écrire. Pour de plus amples informations, veuillez consulter Java 1.x : D ynamoDBMapper.

Note

Cet exemple de code part du principe que vous avez déjà chargé des données dans DynamoDB pour votre compte en suivant les instructions de la section Création de tables et chargement de données pour des exemples de code dans DynamoDB.

Pour step-by-step obtenir des instructions relatives à l'exécution de l'exemple suivant, reportez-vous àExemples de code 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(); } } }