| « PreviousNext » | |
![]() ![]() ![]() | Did this page help you? Yes | No | Tell us about it... |
The query method enables you to query a table. You can query a table only if it
has a primary that is composed of both a hash and range
attribute.
The following are the steps to retrieve an item using the low-level Java 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.
You can provide both the required and optional parameters using this object.
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 Java code snippet demonstrates the preceding tasks. The snippet assumes you have a Reply table that 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 Id attribute of the Reply table is composed of both the forum name and forum subject. The Id and the ReplyDateTime make up the composite hash-and-range primary key for the table.
The following query retrieves all replies for a specific thread subject. The query requires both the table name and the Subject value.
Condition hashKeyCondition = new Condition()
.withComparisonOperator(ComparisonOperator.EQ.toString())
.withAttributeValueList(new AttributeValue().withS("Amazon DynamoDB#DynamoDB Thread 1"));
Map<String, Condition> keyConditions = new HashMap<String, Condition>();
keyConditions.put("Id", hashKeyCondition);
QueryRequest queryRequest = new QueryRequest()
.withTableName("Reply")
.withKeyConditions(keyConditions);
QueryResult result = client.query(queryRequest);
for (Map<String, AttributeValue> item : result.getItems()) {
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 Java code snippet retrieves forum thread replies posted in the past 15 days. The snippet specifies optional parameters using:
A Condition instance 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.
The withAttributesToGet method to specify a list of
attributes to retrieve for items in the query results.
The withConsistentRead method as true to request a strongly consistent read. To learn more about read consistency, see Amazon DynamoDB Data Model .
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);
Map<String, Condition> keyConditions = new HashMap<String, Condition>();
Condition hashKeyCondition = new Condition()
.withComparisonOperator(ComparisonOperator.EQ.toString())
.withAttributeValueList(new AttributeValue().withS("Amazon DynamoDB#DynamoDB Thread 1"));
keyConditions.put("Id", hashKeyCondition);
Condition rangeKeyCondition = new Condition()
.withComparisonOperator(ComparisonOperator.GT.toString())
.withAttributeValueList(new AttributeValue().withS(twoWeeksAgoStr));
keyConditions.put("ReplyDateTime", rangeKeyCondition);
QueryRequest queryRequest = new QueryRequest()
.withTableName("Reply")
.withKeyConditions(keyConditions)
.withAttributesToGet(Arrays.asList("Subject", "ReplyDateTime"))
.withRangeKeyCondition(rangeKeyCondition)
.withConsistentRead(true);
QueryResult result = client.query(queryRequest);
for (Map<String, AttributeValue> item : result.getItems()){
printItem(item);
}
You can also optionally limit the page size, or the number of items per page, by
using the withLimit method of the request. 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 using
the withExclusiveStartKey method. Initially, the parameter for this method
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 Java code snippet queries the Reply table. In the request, the
withLimit and withExclusiveStartKey methods are used. The
do/while loop continues to scan one page at time until the
getLastEvaluatedKey method of the result returns a null value.
Condition hashKeyCondition = new Condition()
.withComparisonOperator(ComparisonOperator.EQ.toString())
.withAttributeValueList(new AttributeValue().withS("Amazon DynamoDB#DynamoDB Thread 1"));
Map<String, Condition> keyConditions = new HashMap<String, Condition>();
keyConditions.put("Id", hashKeyCondition);
Map<String, AttributeValue> lastEvaluatedKey = null;
do {
QueryRequest queryRequest = new QueryRequest()
.withTableName("Reply")
.withKeyConditions(keyConditions)
.withLimit(10)
.withExclusiveStartKey(lastEvaluatedKey);
QueryResult result = client.query(queryRequest);
for (Map<String, AttributeValue> item : result.getItems()) {
printItem(item);
}
lastEvaluatedKey = result.getLastEvaluatedKey();
} while (lastEvaluatedKey != null);
The examples in this section use the AWS SDK for Java low-level API. 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 Java.
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 Java code example, you execute variations of finding 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 illustrates the use of pagination to process multipage results. 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 the preceding two queries shows how you can specify range key conditions to filter query results and use other optional query parameters.
Note
This code example assumes that you have already loaded data into Amazon DynamoDB for your account by following the instructions in the Getting Started section. Alternatively, you can load the data programmatically using the instructions in the Creating Example Tables and Uploading Data Using the AWS SDK for Java Low-Level API topic.
For step-by-step instructions to run the following example, see Running Java Examples for Amazon DynamoDB.
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.PropertiesCredentials;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient;
import com.amazonaws.services.dynamodbv2.model.AttributeValue;
import com.amazonaws.services.dynamodbv2.model.ComparisonOperator;
import com.amazonaws.services.dynamodbv2.model.Condition;
import com.amazonaws.services.dynamodbv2.model.QueryRequest;
import com.amazonaws.services.dynamodbv2.model.QueryResult;
public class LowLevelQuery {
static AmazonDynamoDBClient client;
static String tableName = "Reply";
public static void main(String[] args) throws Exception {
String forumName = "Amazon DynamoDB";
String threadSubject = "DynamoDB Thread 1";
createClient();
findRepliesForAThread(forumName, threadSubject);
findRepliesForAThreadSpecifyOptionalLimit(forumName, threadSubject);
findRepliesInLast15DaysWithConfig(forumName, threadSubject);
findRepliesPostedWithinTimePeriod(forumName, threadSubject);
}
private static void createClient() throws IOException {
AWSCredentials credentials = new PropertiesCredentials(
LowLevelQuery.class.getResourceAsStream("AwsCredentials.properties"));
client = new AmazonDynamoDBClient(credentials);
}
private static void findRepliesForAThread(String forumName, String threadSubject) {
String replyId = forumName + "#" + threadSubject;
Condition hashKeyCondition = new Condition()
.withComparisonOperator(ComparisonOperator.EQ.toString())
.withAttributeValueList(new AttributeValue().withS(replyId));
Map<String, Condition> keyConditions = new HashMap<String, Condition>();
keyConditions.put("Id", hashKeyCondition);
QueryRequest queryRequest = new QueryRequest()
.withTableName(tableName)
.withKeyConditions(keyConditions);
QueryResult result = client.query(queryRequest);
for (Map<String, AttributeValue> item : result.getItems()) {
printItem(item);
}
}
private static void findRepliesForAThreadSpecifyOptionalLimit(String forumName, String threadSubject) {
Map<String, AttributeValue> lastEvaluatedKey = null;
do {
QueryRequest queryRequest = new QueryRequest()
.withTableName(tableName)
.withKeyConditions(makeReplyKeyConditions(forumName, threadSubject))
.withLimit(1)
.withExclusiveStartKey(lastEvaluatedKey);
QueryResult result = client.query(queryRequest);
for (Map<String, AttributeValue> item : result.getItems()) {
printItem(item);
}
lastEvaluatedKey = result.getLastEvaluatedKey();
} while (lastEvaluatedKey != null);
}
private static void findRepliesInLast15DaysWithConfig(String forumName, String threadSubject) {
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);
Condition rangeKeyCondition = new Condition()
.withComparisonOperator(ComparisonOperator.GT.toString())
.withAttributeValueList(new AttributeValue().withS(twoWeeksAgoStr));
Map<String, Condition> keyConditions = makeReplyKeyConditions(forumName, threadSubject);
keyConditions.put("ReplyDateTime", rangeKeyCondition);
QueryRequest queryRequest = new QueryRequest().withTableName(tableName)
.withKeyConditions(keyConditions)
.withAttributesToGet(Arrays.asList("Message", "ReplyDateTime", "PostedBy"));
QueryResult result = client.query(queryRequest);
for (Map<String, AttributeValue> item : result.getItems()) {
printItem(item);
}
}
private static void findRepliesPostedWithinTimePeriod(String forumName, String threadSubject) {
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);
Condition rangeKeyCondition = new Condition()
.withComparisonOperator(ComparisonOperator.BETWEEN.toString())
.withAttributeValueList(
new AttributeValue().withS(startDate),
new AttributeValue().withS(endDate));
Map<String, Condition> keyConditions = makeReplyKeyConditions(forumName, threadSubject);
keyConditions.put("ReplyDateTime", rangeKeyCondition);
QueryRequest queryRequest = new QueryRequest()
.withTableName(tableName)
.withKeyConditions(keyConditions)
.withAttributesToGet(Arrays.asList("Message", "ReplyDateTime", "PostedBy"));
QueryResult result = client.query(queryRequest);
for (Map<String, AttributeValue> item : result.getItems()) {
printItem(item);
}
}
private static void printItem(Map<String, AttributeValue> attributeList) {
for (Map.Entry<String, AttributeValue> item : attributeList.entrySet()) {
String attributeName = item.getKey();
AttributeValue value = item.getValue();
System.out.println(attributeName + " "
+ (value.getS() == null ? "" : "S=[" + value.getS() + "]")
+ (value.getN() == null ? "" : "N=[" + value.getN() + "]")
+ (value.getB() == null ? "" : "B=[" + value.getB() + "]")
+ (value.getSS() == null ? "" : "SS=[" + value.getSS() + "]")
+ (value.getNS() == null ? "" : "NS=[" + value.getNS() + "]")
+ (value.getBS() == null ? "" : "BS=[" + value.getBS() + "] \n"));
}
}
/**
* A simple helper function that returns a KeyCondition map filled in with the hash key equality condition
* for a the Reply example table, given a forumName and threadSubject.
*/
private static Map<String, Condition> makeReplyKeyConditions(String forumName, String threadSubject) {
String replyId = forumName + "#" + threadSubject;
Condition hashKeyCondition = new Condition()
.withComparisonOperator(ComparisonOperator.EQ.toString())
.withAttributeValueList(new AttributeValue().withS(replyId));
Map<String, Condition> keyConditions = new HashMap<String, Condition>();
keyConditions.put("Id", hashKeyCondition);
return keyConditions;
}
}