Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DynamoDB: How to use a query filter to check for conditions in a MAP

I have a table and the structure looks like this:

DynamoDB document

When I do a query, I would like to be able to do a query filter on the data map; but I'm not exactly sure how to setup the query.

This is what I have so far:

HashMap<String, AttributeValue> map = new HashMap<String, AttributeValue>();
map.put("byUserId", new AttributeValue().withS("vl49uga5ljjcoln65rcaspmg8u"));

queryExpression
    .withQueryFilterEntry("data", new Condition()
        .withAttributeValueList(new AttributeValue().withM(map))
        .withComparisonOperator(ComparisonOperator.CONTAINS));

but the way I'm building the filter is not correct and I keep running into the following error:

Exception in thread "main" com.amazonaws.AmazonServiceException: One or more parameter values were invalid: ComparisonOperator CONTAINS is not valid for M AttributeValue type (Service: AmazonDynamoDBv2; Status Code: 400; Error Code: ValidationException; Request ID: CHIOME68L1HVGO81URD7CIOS6BVV4KQNSO5AEMVJF66Q9ASUAAJG)
    at com.amazonaws.http.AmazonHttpClient.handleErrorResponse(AmazonHttpClient.java:1077)
    at com.amazonaws.http.AmazonHttpClient.executeOneRequest(AmazonHttpClient.java:725)
    at com.amazonaws.http.AmazonHttpClient.executeHelper(AmazonHttpClient.java:460)
    at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:295)
    at com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient.invoke(AmazonDynamoDBClient.java:3106)
    at com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient.query(AmazonDynamoDBClient.java:1118)

So what is a comparison operator I should be using (since IN is for list types), and how do I build the query filter such that I can specify a comparison inside of the MAP.

Thanks!

like image 800
ThePedestrian Avatar asked May 09 '15 18:05

ThePedestrian


People also ask

Can conditional operations be used in a DynamoDB query?

Yes, like all the other database management systems, DynamoDB also supports all the conditional operators, User can specify a condition that is satisfied for a put, update, or delete operation to work on an item.

What is the difference between query and scan operations in DynamoDB?

DynamoDB offers two ways to access information stored: Query and Scan. A Query will rely on the primary-key to find information. Query can point directly to a particular item (or set ot items) and retrieve them in a fast and efficient way. Scan, as the name suggests, will browse table items from start to finish.

What does the query operation in Amazon DynamoDB allow you to do?

The Query operation allows you to limit the number of items that it reads. To do this, set the Limit parameter to the maximum number of items that you want. For example, suppose that you Query a table, with a Limit value of 6 , and without a filter expression.


1 Answers

Try comparing the map attribute data.byUserId instead of the entire map structure:

Table table = dynamoDB.getTable(tableName);

Map<String, Object> expressionAttributeValues = new HashMap<String, Object>();
expressionAttributeValues.put(":x", "vl49uga5ljjcoln65rcaspmg8u");


QuerySpec spec = new QuerySpec()
    .withHashKey("HashKeyAttribute", "HashKeyAttributeValue")
    .withFilterExpression("data.byUserId = :x")
    .withValueMap(expressionAttributeValues);


ItemCollection<QueryOutcome> items = table.query(spec);

Iterator<Item> iterator = items.iterator();

while (iterator.hasNext()) {
    System.out.println(iterator.next().toJSONPretty());
}

Some important guidelines:

  1. Make sure the variable tableName has the correct table name represented as a string.

  2. Make sure to replace the string HashKeyAttribute with the attribute name that represents your Hash Key.

  3. Make sure to replace the string HashKeyAttributeValue with the value that represents the Hash Key that you want to match.

  4. Make sure the matched record has the data.byUserId with the value provided in the comparison expression. In the example the value "vl49uga5ljjcoln65rcaspmg8u" was provided.

Here is another example having the id attribute as the Hash Key:

Table table = dynamoDB.getTable(tableName);

Map<String, Object> expressionAttributeValues = new HashMap<String, Object>();
expressionAttributeValues.put(":x", "vl49uga5ljjcoln65rcaspmg8u");


QuerySpec spec = new QuerySpec()
    .withHashKey("id", "25g77vmummpr4mc5mb9vq36q43")
    .withFilterExpression("data.byUserId = :x")
    .withValueMap(expressionAttributeValues);


ItemCollection<QueryOutcome> items = table.query(spec);

Iterator<Item> iterator = items.iterator();

while (iterator.hasNext()) {
    System.out.println(iterator.next().toJSONPretty());
}
like image 160
b-s-d Avatar answered Sep 19 '22 15:09

b-s-d