DynamoDB: How to use a query filter to check for conditions in a MAP
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:
Make sure the variable
tableName
has the correct table name represented as astring
.Make sure to replace the string
HashKeyAttribute
with the attribute name that represents yourHash Key
.Make sure to replace the string
HashKeyAttributeValue
with the value that represents the Hash Key that you want to match.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());
}
ThePedestrian
Updated on July 27, 2022Comments
-
ThePedestrian almost 2 years
I have a table and the structure looks like this:
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!
-
ThePedestrian almost 9 yearsThank you for your response but unfortunately it did not work. :(
-
b-s-d almost 9 yearsCan you provide more details?
-
b-s-d almost 9 yearsWhat is the end result with the provided answer? Error? No results being returned?
-
ThePedestrian almost 9 yearsWonderful!!! Thank you so much! This worked great. Few things I would mention for future readers is that
data
is a reserved keyword. Once, I changed the attribute name, I was able to use @spin code. -
ThePedestrian almost 9 yearsI have one more question. I'm trying to refactor my code to use the high-level API. How do I set the expression attribute values? Is it possible to do in the high-level API? You can view my code here.
-
b-s-d almost 9 yearsI believe these guidelines on how to use placeholders will be helpful on this case: docs.aws.amazon.com/amazondynamodb/latest/developerguide/…
-
Kuldeep Yadav over 5 yearsCan condition be not used for nested attribute data. byUserId?