Esecuzione di query su tabelle e indici: .NET - 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à.

Esecuzione di query su tabelle e indici: .NET

L'operazione Query permette di eseguire query su una tabella o un indice secondario in Amazon DynamoDB. Devi fornire il valore di una chiave di partizione e una condizione di uguaglianza. Se la tabella o l'indice ha una chiave di ordinamento, puoi perfezionare i risultati specificando il valore della chiave di ordinamento e una condizione.

Di seguito sono riportati i passaggi per interrogare una tabella utilizzando l' AWS SDK for .NET API di basso livello.

  1. Creare un'istanza della classe AmazonDynamoDBClient.

  2. Crea un'istanza della classe QueryRequest e specifica i parametri dell'operazione di query.

  3. Eseguire il metodo Query e fornire l'oggetto QueryRequest creato nella fase precedente.

    La risposta include un oggetto QueryResult che fornisce tutti gli elementi restituiti dalla query.

Il seguente esempio di codice C# mostra le attività precedenti. Il codice presuppone che sia disponibile una tabella Reply in cui vengono memorizzate le risposte dei thread di un forum. Per ulteriori informazioni, consulta Creazione di tabelle e caricamento di dati per esempi di codice in DynamoDB.

Esempio
Reply Id, ReplyDateTime, ... )

Ogni thread del forum ha un ID univoco e può avere zero o più risposte. Di conseguenza, la chiave primaria è costituita sia da Id (chiave di partizione) sia da ReplyDateTime (chiave di ordinamento).

La query seguente recupera tutte le risposte per l'oggetto di un thread specifico. La query richiede il nome della tabella e il valore Subject.

Esempio
AmazonDynamoDBClient client = new AmazonDynamoDBClient(); var request = new QueryRequest { TableName = "Reply", KeyConditionExpression = "Id = :v_Id", ExpressionAttributeValues = new Dictionary<string, AttributeValue> { {":v_Id", new AttributeValue { S = "Amazon DynamoDB#DynamoDB Thread 1" }}} }; var response = client.Query(request); foreach (Dictionary<string, AttributeValue> item in response.Items) { // Process the result. PrintItem(item); }

Specifica dei parametri facoltativi

Il metodo Query supporta diversi parametri facoltativi. Ad esempio, puoi facoltativamente limitare il risultato della query precedente in modo da restituire le risposte delle ultime due settimane specificando una condizione. La condizione è chiamata condizione della chiave di ordinamento perché DynamoDB valuta la condizione della query specificata rispetto alla chiave di ordinamento della chiave primaria. Puoi specificare altri parametri facoltativi per recuperare solo un elenco specifico di attributi dagli elementi nel risultato della query. Per ulteriori informazioni, consulta la sezione Query.

L'esempio di codice C# seguente recupera le risposte dei thread del forum pubblicate negli ultimi 15 giorni. L'esempio specifica i parametri facoltativi seguenti:

  • Parametro KeyConditionExpression per recuperare solo le risposte degli ultimi 15 giorni.

  • Parametro ProjectionExpression per specificare un elenco di attributi da recuperare per gli elementi nel risultato della query.

  • Parametro ConsistentRead per eseguire una lettura consistente assoluta.

Esempio
DateTime twoWeeksAgoDate = DateTime.UtcNow - TimeSpan.FromDays(15); string twoWeeksAgoString = twoWeeksAgoDate.ToString(AWSSDKUtils.ISO8601DateFormat); var request = new QueryRequest { TableName = "Reply", KeyConditionExpression = "Id = :v_Id and ReplyDateTime > :v_twoWeeksAgo", ExpressionAttributeValues = new Dictionary<string, AttributeValue> { {":v_Id", new AttributeValue { S = "Amazon DynamoDB#DynamoDB Thread 2" }}, {":v_twoWeeksAgo", new AttributeValue { S = twoWeeksAgoString }} }, ProjectionExpression = "Subject, ReplyDateTime, PostedBy", ConsistentRead = true }; var response = client.Query(request); foreach (Dictionary<string, AttributeValue> item in response.Items) { // Process the result. PrintItem(item); }

Puoi anche scegliere di limitare la dimensione della pagina o il numero di item per pagina aggiungendo il parametro facoltativo Limit. Ogni volta che viene eseguito il metodo Query, si ottiene una pagina di risultati contenente il numero specificato di elementi. Per recuperare la pagina successiva, è necessario eseguire di nuovo il metodo Query fornendo il valore della chiave primaria dell'ultimo elemento nella pagina precedente, in modo che il metodo possa restituire il set successivo di elementi. Fornisci queste informazioni nella richiesta impostando la proprietà ExclusiveStartKey. Inizialmente, questa proprietà può essere null. Per recuperare le pagine successive, devi aggiornare questo valore di proprietà alla chiave primaria dell'ultimo item nella pagina precedente.

Il seguente esempio C# esegue una query sulla tabella Reply. Nella richiesta vengono specificati i parametri facoltativi Limit ed ExclusiveStartKey. Il ciclo do/while continua a eseguire la scansione di una pagina per volta finché LastEvaluatedKey non restituisce un valore null.

Esempio
Dictionary<string,AttributeValue> lastKeyEvaluated = null; do { var request = new QueryRequest { TableName = "Reply", KeyConditionExpression = "Id = :v_Id", ExpressionAttributeValues = new Dictionary<string, AttributeValue> { {":v_Id", new AttributeValue { S = "Amazon DynamoDB#DynamoDB Thread 2" }} }, // Optional parameters. Limit = 1, ExclusiveStartKey = lastKeyEvaluated }; var response = client.Query(request); // Process the query result. foreach (Dictionary<string, AttributeValue> item in response.Items) { PrintItem(item); } lastKeyEvaluated = response.LastEvaluatedKey; } while (lastKeyEvaluated != null && lastKeyEvaluated.Count != 0);

Esempio: esecuzione di interrogazioni utilizzando il AWS SDK for .NET

Nelle tabelle seguenti sono archiviate informazioni su una raccolta di forum. Per ulteriori informazioni, consulta Creazione di tabelle e caricamento di dati per esempi di codice in DynamoDB.

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

In questo esempio, vengono eseguite variazioni di "Trova risposte per un thread DynamoDB 1" nel forum "DynamoDB".

  • Ricerca di risposte per un thread.

  • Ricerca di risposte per un thread. Specifica il parametro di query Limit per impostare le dimensioni della pagina.

    Questa funzione illustra l'uso dell'impaginazione per elaborare il risultato multipagina. Se DynamoDB ha un limite di dimensioni della pagina e se il risultato supera tale limite, viene restituita solo la prima pagina di risultati. Questo modello di codifica garantisce che il codice elabori tutte le pagine nel risultato della query.

  • Ricerca di risposte negli ultimi 15 giorni.

  • Ricerca di risposte in un intervallo di date specifico.

    Le due query precedenti mostrano come specificare le condizioni della chiave di ordinamento per limitare i risultati della query e usare parametri di query facoltativi.

Per step-by-step istruzioni su come testare l'esempio seguente, vedereEsempi di codice .NET.

using System; using System.Collections.Generic; using Amazon.DynamoDBv2; using Amazon.DynamoDBv2.Model; using Amazon.Runtime; using Amazon.Util; namespace com.amazonaws.codesamples { class LowLevelQuery { private static AmazonDynamoDBClient client = new AmazonDynamoDBClient(); static void Main(string[] args) { try { // Query a specific forum and thread. string forumName = "Amazon DynamoDB"; string threadSubject = "DynamoDB Thread 1"; FindRepliesForAThread(forumName, threadSubject); FindRepliesForAThreadSpecifyOptionalLimit(forumName, threadSubject); FindRepliesInLast15DaysWithConfig(forumName, threadSubject); FindRepliesPostedWithinTimePeriod(forumName, threadSubject); Console.WriteLine("Example complete. To continue, press Enter"); Console.ReadLine(); } catch (AmazonDynamoDBException e) { Console.WriteLine(e.Message); Console.ReadLine(); } catch (AmazonServiceException e) { Console.WriteLine(e.Message); Console.ReadLine(); } catch (Exception e) { Console.WriteLine(e.Message); Console.ReadLine(); } } private static void FindRepliesPostedWithinTimePeriod(string forumName, string threadSubject) { Console.WriteLine("*** Executing FindRepliesPostedWithinTimePeriod() ***"); string replyId = forumName + "#" + threadSubject; // You must provide date value based on your test data. DateTime startDate = DateTime.UtcNow - TimeSpan.FromDays(21); string start = startDate.ToString(AWSSDKUtils.ISO8601DateFormat); // You provide date value based on your test data. DateTime endDate = DateTime.UtcNow - TimeSpan.FromDays(5); string end = endDate.ToString(AWSSDKUtils.ISO8601DateFormat); var request = new QueryRequest { TableName = "Reply", ReturnConsumedCapacity = "TOTAL", KeyConditionExpression = "Id = :v_replyId and ReplyDateTime between :v_start and :v_end", ExpressionAttributeValues = new Dictionary<string, AttributeValue> { {":v_replyId", new AttributeValue { S = replyId }}, {":v_start", new AttributeValue { S = start }}, {":v_end", new AttributeValue { S = end }} } }; var response = client.Query(request); Console.WriteLine("\nNo. of reads used (by query in FindRepliesPostedWithinTimePeriod) {0}", response.ConsumedCapacity.CapacityUnits); foreach (Dictionary<string, AttributeValue> item in response.Items) { PrintItem(item); } Console.WriteLine("To continue, press Enter"); Console.ReadLine(); } private static void FindRepliesInLast15DaysWithConfig(string forumName, string threadSubject) { Console.WriteLine("*** Executing FindRepliesInLast15DaysWithConfig() ***"); string replyId = forumName + "#" + threadSubject; DateTime twoWeeksAgoDate = DateTime.UtcNow - TimeSpan.FromDays(15); string twoWeeksAgoString = twoWeeksAgoDate.ToString(AWSSDKUtils.ISO8601DateFormat); var request = new QueryRequest { TableName = "Reply", ReturnConsumedCapacity = "TOTAL", KeyConditionExpression = "Id = :v_replyId and ReplyDateTime > :v_interval", ExpressionAttributeValues = new Dictionary<string, AttributeValue> { {":v_replyId", new AttributeValue { S = replyId }}, {":v_interval", new AttributeValue { S = twoWeeksAgoString }} }, // Optional parameter. ProjectionExpression = "Id, ReplyDateTime, PostedBy", // Optional parameter. ConsistentRead = true }; var response = client.Query(request); Console.WriteLine("No. of reads used (by query in FindRepliesInLast15DaysWithConfig) {0}", response.ConsumedCapacity.CapacityUnits); foreach (Dictionary<string, AttributeValue> item in response.Items) { PrintItem(item); } Console.WriteLine("To continue, press Enter"); Console.ReadLine(); } private static void FindRepliesForAThreadSpecifyOptionalLimit(string forumName, string threadSubject) { Console.WriteLine("*** Executing FindRepliesForAThreadSpecifyOptionalLimit() ***"); string replyId = forumName + "#" + threadSubject; Dictionary<string, AttributeValue> lastKeyEvaluated = null; do { var request = new QueryRequest { TableName = "Reply", ReturnConsumedCapacity = "TOTAL", KeyConditionExpression = "Id = :v_replyId", ExpressionAttributeValues = new Dictionary<string, AttributeValue> { {":v_replyId", new AttributeValue { S = replyId }} }, Limit = 2, // The Reply table has only a few sample items. So the page size is smaller. ExclusiveStartKey = lastKeyEvaluated }; var response = client.Query(request); Console.WriteLine("No. of reads used (by query in FindRepliesForAThreadSpecifyLimit) {0}\n", response.ConsumedCapacity.CapacityUnits); foreach (Dictionary<string, AttributeValue> item in response.Items) { PrintItem(item); } lastKeyEvaluated = response.LastEvaluatedKey; } while (lastKeyEvaluated != null && lastKeyEvaluated.Count != 0); Console.WriteLine("To continue, press Enter"); Console.ReadLine(); } private static void FindRepliesForAThread(string forumName, string threadSubject) { Console.WriteLine("*** Executing FindRepliesForAThread() ***"); string replyId = forumName + "#" + threadSubject; var request = new QueryRequest { TableName = "Reply", ReturnConsumedCapacity = "TOTAL", KeyConditionExpression = "Id = :v_replyId", ExpressionAttributeValues = new Dictionary<string, AttributeValue> { {":v_replyId", new AttributeValue { S = replyId }} } }; var response = client.Query(request); Console.WriteLine("No. of reads used (by query in FindRepliesForAThread) {0}\n", response.ConsumedCapacity.CapacityUnits); foreach (Dictionary<string, AttributeValue> item in response.Items) { PrintItem(item); } Console.WriteLine("To continue, press Enter"); Console.ReadLine(); } private static void PrintItem( Dictionary<string, AttributeValue> attributeList) { foreach (KeyValuePair<string, AttributeValue> kvp in attributeList) { string attributeName = kvp.Key; AttributeValue value = kvp.Value; Console.WriteLine( attributeName + " " + (value.S == null ? "" : "S=[" + value.S + "]") + (value.N == null ? "" : "N=[" + value.N + "]") + (value.SS == null ? "" : "SS=[" + string.Join(",", value.SS.ToArray()) + "]") + (value.NS == null ? "" : "NS=[" + string.Join(",", value.NS.ToArray()) + "]") ); } Console.WriteLine("************************************************"); } } }