| « PreviousNext » | |
![]() ![]() ![]() | Did this page help you? Yes | No | Tell us about it... |
The Query method enables you to query a table. You can only query a table that
has a primary key composed of hash and range attributes.
The following are the steps to query a table using low-level .NET SDK API.
Create an instance of the AmazonDynamoDBClient class and provide your
credentials.
Create an instance of the QueryRequest class and provide query
operation parameters.
Execute the Query method and provide the QueryRequest
object that you created in the preceding step.
The response includes the QueryResult object that provides all items
returned by the query.
The following C# code snippet demonstrates the preceding tasks. The snippet assumes you have a Reply table stores replies for forum threads. For more information, see Example Tables and Data in Amazon DynamoDB.
Reply ( Id, ReplyDateTime, ... )
Each forum thread has a unique ID and can have zero or more replies. Therefore, the primary key is composed of both the Id (hash attribute) and ReplyDateTime (range attribute).
The following query retrieves all replies for a specific thread subject. The query requires both the table name and the Subject value.
var request = new QueryRequest
{
TableName = "Reply",
KeyConditions = new Dictionary<string,Condition>()
{
{
"Id",
new Condition()
{
ComparisonOperator = "EQ",
AttributeValueList = new List<AttributeValue>()
{
new AttributeValue { S = "Amazon DynamoDB#DynamoDB Thread 1" }
}
}
}
}
};
var response = client.Query(request);
var result = response.QueryResult;
foreach (Dictionary<string, AttributeValue> item in response.QueryResult.Items)
{
// Process the result.
PrintItem(item);
}
The Query method supports several optional parameters. For example, you can
optionally filter the query result in the preceding query to return replies in the past two
weeks by specifying a condition. The condition is called range condition because Amazon
DynamoDB evaluates the query condition that you specify against the range attribute of the
primary key. You can specify other optional parameters to retrieve only a specific list of
attributes from items in the query result. For more information about the parameters and the
API, see Query.
The following C# code snippet retrieves forum thread replies posted in the past 15 days. The snippet specifies the following optional parameters:
A RangeKeyCondition parameter to retrieve only the replies in the past
15 days.
The condition specifies a ReplyDateTime value and a comparison operator to use for comparing dates.
An AttributesToGet parameter to specify a list of attributes to retrieve for
items in the query result.
A ConsistentRead parameter to perform a strongly consistent read. To learn more about
read consistency, see Amazon DynamoDB Data Model .
DateTime twoWeeksAgoDate = DateTime.UtcNow - TimeSpan.FromDays(15);
string twoWeeksAgoString = twoWeeksAgoDate.ToString(AWSSDKUtils.ISO8601DateFormat);
var request = new QueryRequest
{
TableName = "Reply",
KeyConditions = new Dictionary<string,Condition>()
{
{
"Id",
new Condition()
{
ComparisonOperator = "EQ",
AttributeValueList = new List<AttributeValue>()
{
new AttributeValue { S = "Amazon DynamoDB#DynamoDB Thread 2" }
}
}
}
},
{
{
"ReplyDateTime",
new Condition()
{
ComparisonOperator = "GT",
AttributeValueList = new List<AttributeValue>()
{
new AttributeValue { S = twoWeeksAgoString }
}
}
}
},
AttributesToGet = new List<string> { "Subject", "ReplyDateTime", "PostedBy" },
ConsistentRead = true
};
var response = client.Query(request);
var result = response.QueryResult;
foreach (Dictionary<string, AttributeValue> item
in response.QueryResult.Items)
{
// Process the result.
PrintItem(item);
}You can also optionally limit the page size, or the number of items per page, by
adding the optional Limit parameter. Each time you execute the Query
method, you get one page of results that has the specified number of items. To fetch the next
page, you execute the Query method again by providing the primary key value of
the last item in the previous page so that the method can return the next set of items. You
provide this information in the request by setting the ExclusiveStartKey
property. Initially, this property can be null. To retrieve subsequent pages, you must update
this property value to the primary key of the last item in the preceding page.
The following C# code snippet queries the Reply table. In the request, it specifies the
Limit and ExclusiveStartKey optional parameters. The
do/while loop continues to scan one page at time until the
LastEvaluatedKey returns a null value.
Dictionary<string,AttributeValue> lastKeyEvaluated = null;
do
{
var request = new QueryRequest
{
TableName = "Reply",
KeyConditions = new Dictionary<string,Condition>()
{
{
"Id",
new Condition()
{
ComparisonOperator = "EQ",
AttributeValueList = new List<AttributeValue>()
{
new AttributeValue { S = "Amazon DynamoDB#DynamoDB Thread 2" }
}
}
}
},
// Optional parameters.
Limit = 10,
ExclusiveStartKey = lastKeyEvaluated
};
var response = client.Query(request);
// Process the query result.
foreach (Dictionary<string, AttributeValue> item in response.QueryResult.Items)
{
PrintItem(item);
}
lastKeyEvaluated = response.QueryResult.LastEvaluatedKey;
} while (lastKeyEvaluated != null);
The examples in this section use AWS SDK for .NET low-level API. The SDK also supports helper API that further simplify your application development. Additionally, the SDK provides Object Persistence Model API that enable you to map your client-side classes to your Amazon DynamoDB tables and perform query operations on them. For more information, see Using the AWS SDK for .NET.
The following tables store information about a collection of forums. For more information about table schemas, see Example Tables and Data in Amazon DynamoDB.
Forum ( Name, ... ) Thread ( ForumName, Subject, Message, LastPostedBy, LastPostDateTime, ...) Reply ( Id, ReplyDateTime, Message, PostedBy, ...)
In this C# code example, you execute variations of "Find replies for a thread "DynamoDB Thread 1" in forum "Amazon DynamoDB".
Find replies for a thread.
Find replies for a thread. Specify the Limit query parameter to set page size.
This function illustrate the use of pagination to process multipage result. Amazon DynamoDB has a page size limit and if your result exceeds the page size, you get only the first page of results. This coding pattern ensures your code processes all the pages in the query result.
Find replies in the last 15 days.
Find replies in a specific date range.
Both of the preceding two queries shows how you can specify range key conditions to filter query results and use other optional query parameters.
For step-by-step instructions to test the following sample, see Using the AWS SDK for .NET.
using System;
using System.Collections.Generic;
using Amazon.DynamoDBv2;
using Amazon.DynamoDBv2.Model;
using Amazon.Runtime;
using Amazon.Util;
namespace Amazon.DynamoDBv2.Documentation
{
class Program
{
private static AmazonDynamoDBClient client;
static void Main(string[] args)
{
try
{
var config = new AmazonDynamoDBConfig();
config.ServiceURL = System.Configuration.ConfigurationManager.AppSettings["ServiceURL"];
client = new AmazonDynamoDBClient(config);
// 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); }
catch (AmazonServiceException e) { Console.WriteLine(e.Message); }
catch (Exception e) { Console.WriteLine(e.Message); }
}
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",
KeyConditions = new Dictionary<string, Condition>()
{
{
"Id",
new Condition()
{
ComparisonOperator = "EQ",
AttributeValueList = new List<AttributeValue>()
{
new AttributeValue { S = replyId }
}
}
},
{
"ReplyDateTime",
new Condition
{
ComparisonOperator = "BETWEEN",
AttributeValueList = new List<AttributeValue>()
{
new AttributeValue { S = start },
new AttributeValue { S = end }
}
}
}
}
};
var response = client.Query(request);
var result = response.QueryResult;
Console.WriteLine("\nNo. of reads used (by query in FindRepliesPostedWithinTimePeriod) {0}",
response.QueryResult.ConsumedCapacity.CapacityUnits);
foreach (Dictionary<string, AttributeValue> item
in response.QueryResult.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",
KeyConditions = new Dictionary<string, Condition>()
{
{
"Id",
new Condition
{
ComparisonOperator = "EQ",
AttributeValueList = new List<AttributeValue>()
{
new AttributeValue { S = replyId }
}
}
},
{
"ReplyDateTime",
new Condition
{
ComparisonOperator = "GT",
AttributeValueList = new List<AttributeValue>()
{
new AttributeValue { S = twoWeeksAgoString }
}
}
}
},
// Optional parameter.
AttributesToGet = new List<string> { "Id", "ReplyDateTime", "PostedBy" },
// Optional parameter.
ConsistentRead = true
};
var response = client.Query(request);
var result = response.QueryResult;
Console.WriteLine("No. of reads used (by query in FindRepliesInLast15DaysWithConfig) {0}",
response.QueryResult.ConsumedCapacity.CapacityUnits);
foreach (Dictionary<string, AttributeValue> item
in response.QueryResult.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",
KeyConditions = new Dictionary<string, Condition>()
{
{
"Id",
new Condition
{
ComparisonOperator = "EQ",
AttributeValueList = new List<AttributeValue>()
{
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.QueryResult.ConsumedCapacity.CapacityUnits);
foreach (Dictionary<string, AttributeValue> item
in response.QueryResult.Items)
{
PrintItem(item);
}
lastKeyEvaluated = response.QueryResult.LastEvaluatedKey;
} while (lastKeyEvaluated != null);
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",
KeyConditions = new Dictionary<string, Condition>()
{
{
"Id",
new Condition
{
ComparisonOperator = "EQ",
AttributeValueList = new List<AttributeValue>()
{
new AttributeValue { S = replyId }
}
}
}
}
};
var response = client.Query(request);
var result = response.QueryResult;
Console.WriteLine("No. of reads used (by query in FindRepliesForAThread) {0}\n",
response.QueryResult.ConsumedCapacity.CapacityUnits);
foreach (Dictionary<string, AttributeValue> item
in response.QueryResult.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("************************************************");
}
}
}