Interrogation de tables et d'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.

Interrogation de tables et d'index : Java

L'opération Query vous permet d'interroger une table ou un index secondaire dans Amazon DynamoDB. Vous devez fournir une valeur de clé de partition et une condition d'égalité. Si la table ou l'index dispose d'une clé de tri, vous pouvez affiner les résultats en fournissant une valeur de clé de tri et une condition.

Note

AWS SDK for Java Il 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 : DynamoDBMapper.

Voici les étapes à suivre pour récupérer un élément à l'aide de l'API AWS SDK for Java Document.

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

  2. Créez une instance de la classe Table pour représenter la table que vous souhaitez utiliser.

  3. Appelez la méthode query de l'instance Table. Vous devez spécifier la valeur de clé de partition du ou des éléments que vous souhaitez récupérer, ainsi que de n'importe quel paramètre facultatif d'interrogation.

La réponse inclut un objet ItemCollection qui fournit tous les éléments renvoyés par la requête.

L'exemple de code Java suivant présente les tâches précédentes. L'exemple suppose que vous ayez une table Reply qui stocke les réponses pour les threads de forum. Pour de plus amples informations, veuillez consulter Création de tables et chargement de données pour des exemples de code dans DynamoDB.

Reply ( Id, ReplyDateTime, ... )

Chaque thread de forum a un ID unique et peut avoir zéro ou plusieurs réponses. Par conséquent, l'attribut Id de la table Reply est composé du nom du forum et de l'objet du forum. Id (clé de partition) et ReplyDateTime (clé de tri) composent la clé principale composite de la table.

La requête suivante récupère toutes les réponses pour un objet thread spécifique. La requête requiert à la fois le nom de la table et la valeur Subject.

Exemple
AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard() .withRegion(Regions.US_WEST_2).build(); DynamoDB dynamoDB = new DynamoDB(client); Table table = dynamoDB.getTable("Reply"); QuerySpec spec = new QuerySpec() .withKeyConditionExpression("Id = :v_id") .withValueMap(new ValueMap() .withString(":v_id", "Amazon DynamoDB#DynamoDB Thread 1")); ItemCollection<QueryOutcome> items = table.query(spec); Iterator<Item> iterator = items.iterator(); Item item = null; while (iterator.hasNext()) { item = iterator.next(); System.out.println(item.toJSONPretty()); }

Spécification de paramètres facultatifs

La méthode query prend en charge plusieurs paramètres facultatifs. Par exemple, vous pouvez le cas échéant affiner les résultats de la requête précédente pour renvoyer des réponses des deux semaines écoulées en spécifiant une condition. La condition est appelée condition de clé de tri parce que DynamoDB évalue la condition de la requête que vous spécifiez par rapport à la clé de tri de la clé primaire. Vous pouvez spécifier d'autres paramètres facultatifs pour récupérer uniquement une liste spécifique d'attributs des éléments du résultat de la requête.

L'exemple de code Java suivant récupère les réponses des threads de forum publiées au cours des 15 derniers jours. L'échantillon spécifie les paramètres facultatifs suivants :

  • Une KeyConditionExpression pour récupérer les réponses à partir d'un forum de discussion spécifique (clé de partition) et, au sein de cet ensemble d'éléments, des réponses qui ont été publiées au cours des 15 derniers jours (clé de tri).

  • Une FilterExpression pour renvoyer uniquement les réponses à partir d'un utilisateur spécifique. Le filtre est appliqué une fois la requête traitée, mais avant que les résultats soient renvoyés à l'utilisateur.

  • Une ValueMap pour définir les valeurs réelles pour les espaces réservés KeyConditionExpression.

  • Un paramètre ConsistentRead true pour demander une lecture fortement cohérente.

Cet exemple utilise un objet QuerySpec qui permet d'accéder à tous les paramètres d'entrée Query de bas niveau.

Exemple
Table table = dynamoDB.getTable("Reply"); long twoWeeksAgoMilli = (new Date()).getTime() - (15L*24L*60L*60L*1000L); Date twoWeeksAgo = new Date(); twoWeeksAgo.setTime(twoWeeksAgoMilli); SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"); String twoWeeksAgoStr = df.format(twoWeeksAgo); QuerySpec spec = new QuerySpec() .withKeyConditionExpression("Id = :v_id and ReplyDateTime > :v_reply_dt_tm") .withFilterExpression("PostedBy = :v_posted_by") .withValueMap(new ValueMap() .withString(":v_id", "Amazon DynamoDB#DynamoDB Thread 1") .withString(":v_reply_dt_tm", twoWeeksAgoStr) .withString(":v_posted_by", "User B")) .withConsistentRead(true); ItemCollection<QueryOutcome> items = table.query(spec); Iterator<Item> iterator = items.iterator(); while (iterator.hasNext()) { System.out.println(iterator.next().toJSONPretty()); }

Vous pouvez également le cas échéant limiter le nombre d'éléments par page en utilisant la méthode withMaxPageSize. Lorsque vous appelez la méthode query, vous obtenez une ItemCollection qui contient les éléments qui en résultent. Vous pouvez ensuite parcourir les résultats, en traitant une page à la fois, jusqu'à ce qu'il n'y ait pas plus de pages.

L'exemple de code Java suivant modifie la spécification de requête présentée ci-dessus. Cette fois-ci, la spécification de requête utilise la méthode withMaxPageSize. La classe Page fournit un itérateur qui permet au code de traiter les éléments de chaque page.

Exemple
spec.withMaxPageSize(10); ItemCollection<QueryOutcome> items = table.query(spec); // Process each page of results int pageNum = 0; for (Page<Item, QueryOutcome> page : items.pages()) { System.out.println("\nPage: " + ++pageNum); // Process each item on the current page Iterator<Item> item = page.iterator(); while (item.hasNext()) { System.out.println(item.next().toJSONPretty()); } }

Exemple – Interrogation avec Java

Les tables suivantes stockent des informations sur un ensemble de forums. Pour de plus amples informations, veuillez consulter Création de tables et chargement de données pour des exemples de code dans DynamoDB.

Note

Le kit SDK pour Java fournit également un modèle de persistance des objets qui vous permet de mapper vos classes côté client à des 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 : DynamoDBMapper.

Exemple
Forum ( Name, ... ) Thread ( ForumName, Subject, Message, LastPostedBy, LastPostDateTime, ...) Reply ( Id, ReplyDateTime, Message, PostedBy, ...)

Dans cet exemple de code Java, vous exécutez des variantes de recherche des réponses pour une unité d’exécution « DynamoDB Thread 1 » dans le forum « DynamoDB ».

  • Recherchez des réponses pour un thread.

  • Recherchez des réponses pour un thread, en spécifiant une limite sur le nombre d'éléments par page de résultats. Si le nombre d'éléments dans l'ensemble de résultats dépasse la taille de la page, vous obtenez uniquement la première page de résultats. Ce modèle de codage garantit que votre code traite toutes les pages dans le résultat de la requête.

  • Recherchez des réponses au cours des 15 derniers jours.

  • Recherchez des réponses dans une plage de dates spécifique.

    Les deux requêtes précédentes vous montrent comment vous pouvez spécifier des conditions de clé de tri pour affiner les résultats de la requête et utiliser d'autres paramètres de requête facultatifs.

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 sur l'exécution de l'exemple suivant, reportez-vous àExemples de code Java.

package com.amazonaws.codesamples.document; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Iterator; 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.Page; import com.amazonaws.services.dynamodbv2.document.QueryOutcome; import com.amazonaws.services.dynamodbv2.document.Table; import com.amazonaws.services.dynamodbv2.document.spec.QuerySpec; import com.amazonaws.services.dynamodbv2.document.utils.ValueMap; public class DocumentAPIQuery { static AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard().build(); static DynamoDB dynamoDB = new DynamoDB(client); static String tableName = "Reply"; public static void main(String[] args) throws Exception { String forumName = "Amazon DynamoDB"; String threadSubject = "DynamoDB Thread 1"; findRepliesForAThread(forumName, threadSubject); findRepliesForAThreadSpecifyOptionalLimit(forumName, threadSubject); findRepliesInLast15DaysWithConfig(forumName, threadSubject); findRepliesPostedWithinTimePeriod(forumName, threadSubject); findRepliesUsingAFilterExpression(forumName, threadSubject); } private static void findRepliesForAThread(String forumName, String threadSubject) { Table table = dynamoDB.getTable(tableName); String replyId = forumName + "#" + threadSubject; QuerySpec spec = new QuerySpec().withKeyConditionExpression("Id = :v_id") .withValueMap(new ValueMap().withString(":v_id", replyId)); ItemCollection<QueryOutcome> items = table.query(spec); System.out.println("\nfindRepliesForAThread results:"); Iterator<Item> iterator = items.iterator(); while (iterator.hasNext()) { System.out.println(iterator.next().toJSONPretty()); } } private static void findRepliesForAThreadSpecifyOptionalLimit(String forumName, String threadSubject) { Table table = dynamoDB.getTable(tableName); String replyId = forumName + "#" + threadSubject; QuerySpec spec = new QuerySpec().withKeyConditionExpression("Id = :v_id") .withValueMap(new ValueMap().withString(":v_id", replyId)).withMaxPageSize(1); ItemCollection<QueryOutcome> items = table.query(spec); System.out.println("\nfindRepliesForAThreadSpecifyOptionalLimit results:"); // Process each page of results int pageNum = 0; for (Page<Item, QueryOutcome> page : items.pages()) { System.out.println("\nPage: " + ++pageNum); // Process each item on the current page Iterator<Item> item = page.iterator(); while (item.hasNext()) { System.out.println(item.next().toJSONPretty()); } } } private static void findRepliesInLast15DaysWithConfig(String forumName, String threadSubject) { Table table = dynamoDB.getTable(tableName); long twoWeeksAgoMilli = (new Date()).getTime() - (15L * 24L * 60L * 60L * 1000L); Date twoWeeksAgo = new Date(); twoWeeksAgo.setTime(twoWeeksAgoMilli); SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"); String twoWeeksAgoStr = df.format(twoWeeksAgo); String replyId = forumName + "#" + threadSubject; QuerySpec spec = new QuerySpec().withProjectionExpression("Message, ReplyDateTime, PostedBy") .withKeyConditionExpression("Id = :v_id and ReplyDateTime <= :v_reply_dt_tm") .withValueMap(new ValueMap().withString(":v_id", replyId).withString(":v_reply_dt_tm", twoWeeksAgoStr)); ItemCollection<QueryOutcome> items = table.query(spec); System.out.println("\nfindRepliesInLast15DaysWithConfig results:"); Iterator<Item> iterator = items.iterator(); while (iterator.hasNext()) { System.out.println(iterator.next().toJSONPretty()); } } private static void findRepliesPostedWithinTimePeriod(String forumName, String threadSubject) { Table table = dynamoDB.getTable(tableName); long startDateMilli = (new Date()).getTime() - (15L * 24L * 60L * 60L * 1000L); long endDateMilli = (new Date()).getTime() - (5L * 24L * 60L * 60L * 1000L); java.text.SimpleDateFormat df = new java.text.SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"); String startDate = df.format(startDateMilli); String endDate = df.format(endDateMilli); String replyId = forumName + "#" + threadSubject; QuerySpec spec = new QuerySpec().withProjectionExpression("Message, ReplyDateTime, PostedBy") .withKeyConditionExpression("Id = :v_id and ReplyDateTime between :v_start_dt and :v_end_dt") .withValueMap(new ValueMap().withString(":v_id", replyId).withString(":v_start_dt", startDate) .withString(":v_end_dt", endDate)); ItemCollection<QueryOutcome> items = table.query(spec); System.out.println("\nfindRepliesPostedWithinTimePeriod results:"); Iterator<Item> iterator = items.iterator(); while (iterator.hasNext()) { System.out.println(iterator.next().toJSONPretty()); } } private static void findRepliesUsingAFilterExpression(String forumName, String threadSubject) { Table table = dynamoDB.getTable(tableName); String replyId = forumName + "#" + threadSubject; QuerySpec spec = new QuerySpec().withProjectionExpression("Message, ReplyDateTime, PostedBy") .withKeyConditionExpression("Id = :v_id").withFilterExpression("PostedBy = :v_postedby") .withValueMap(new ValueMap().withString(":v_id", replyId).withString(":v_postedby", "User B")); ItemCollection<QueryOutcome> items = table.query(spec); System.out.println("\nfindRepliesUsingAFilterExpression results:"); Iterator<Item> iterator = items.iterator(); while (iterator.hasNext()) { System.out.println(iterator.next().toJSONPretty()); } } }