Consulta de tabelas e índices: .NET
A operação Query
permite consultar uma tabela ou um índice secundário no Amazon DynamoDB. Você deve fornecer um valor de chave de partição e uma condição de igualdade. Se a tabela ou o índice tiver uma chave de classificação, você poderá refinar os resultados fornecendo um valor de chave de classificação e uma condição.
As seguintes são as etapas para consultar uma tabela usando a API de baixo nível do AWS SDK for .NET.
-
Crie uma instância da classe
AmazonDynamoDBClient
. -
Crie uma instância da classe
QueryRequest
e forneça parâmetros de operação de consulta. -
Execute o método
Query
e forneça o objetoQueryRequest
que você criou na etapa anterior.A resposta inclui o objeto
QueryResult
, que fornece todos os itens retornados pela consulta.
O exemplo de código C# a seguir demonstra as tarefas anteriores. O código pressupõe que você tem uma tabela Reply
que armazena respostas para threads de fórum. Para ter mais informações, consulte Criar tabelas e carregar dados para exemplos de código no DynamoDB.
exemplo
Reply Id, ReplyDateTime, ... )
Cada tópico de fórum tem um ID exclusivo e pode ter zero ou mais respostas. Portanto, a chave primária é composta de Id
(chave de partição) e ReplyDateTime
(chave de classificação).
A consulta a seguir recupera todas as respostas de um assunto de conversa específico. A consulta requer o nome da tabela e o valor de Subject
.
exemplo
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); }
Especificar parâmetros opcionais
O método Query
aceita vários parâmetros opcionais. Por exemplo, você pode opcionalmente refinar o resultado da consulta na consulta anterior para retornar respostas nas últimas duas semanas, especificando uma condição. A condição é chamada de condição de chave de classificação, pois o DynamoDB avalia a condição de consulta que você especifica de acordo com a chave de classificação da chave primária. É possível especificar outros parâmetros opcionais para recuperar apenas uma lista específica de atributos dos itens no resultado da consulta. Para obter mais informações, consulte Consulta.
O exemplo de código C# a seguir recupera respostas a threads de fórum postadas nos últimos 15 dias. O exemplo especifica os seguintes parâmetros opcionais:
-
Uma
KeyConditionExpression
para recuperar somente as respostas nos últimos 15 dias. -
Um parâmetro
ProjectionExpression
para especificar uma lista de atributos a ser recuperada para itens nos resultados da consulta. -
Um parâmetro
ConsistentRead
para realizar uma leitura fortemente consistente.
exemplo
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); }
Opcionalmente, você também pode limitar o tamanho da página, ou o número de itens por página, usando o parâmetro opcional Limit
. Cada vez que executa o método Query
, você obtém uma página de resultados que possui o número de itens especificado. Para buscar a próxima página, execute o método Query
novamente, fornecendo o valor de chave primária do último item da página anterior, para que o método possa recuperar o próximo conjunto de itens. Você fornece essas informações na solicitação, definindo a propriedade ExclusiveStartKey
. Inicialmente, essa propriedade pode ser nula. Para recuperar páginas subsequentes, você deve atualizar esse valor de propriedade para a chave primária do último item da página anterior.
O seguinte exemplo de código C# consulta a tabela Reply
. Na solicitação, ele especifica os parâmetros opcionais Limit
e ExclusiveStartKey
. O loop do/while
continua a verificar uma página por vez até que LastEvaluatedKey
retorne um valor nulo.
exemplo
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);
Exemplo: consultar usando o AWS SDK for .NET
As tabelas a seguir armazenam informações sobre um conjunto de fóruns. Para ter mais informações, consulte Criar tabelas e carregar dados para exemplos de código no DynamoDB.
exemplo
Forum ( Name, ... ) Thread ( ForumName, Subject, Message, LastPostedBy, LastPostDateTime, ...) Reply ( Id, ReplyDateTime, Message, PostedBy, ...)
Neste exemplo de código, você executa variações de Encontrar respostas para um thread "DynamoDB Thread 1" no fórum "DynamoDB".
-
Encontrar respostas para um tópico.
-
Encontrar respostas para um tópico. Especifique o parâmetro de consulta
Limit
para definir o tamanho da página.Essa função ilustra o uso da paginação para processar resultados de várias páginas. O DynamoDB tem um limite de tamanho de página e, se o seu resultado exceder esse limite, você receberá apenas a primeira página de resultados. Esse padrão de codificação assegura que o seu código processe todas as páginas no resultado da consulta.
-
Encontrar respostas nos últimos 15 dias.
-
Encontrar respostas em um intervalo de datas específico.
As duas consultas anteriores mostram como você pode especificar condições de chave de classificação para restringir os resultados da consulta e usar outros parâmetros de consulta opcionais.
Para obter instruções passo a passo sobre como testar o exemplo a seguir, consulte Exemplos de código .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("************************************************"); } } }