1

I need to check list of data with contains function is DynamoDB. Following is my Java Code,

List<String> dataList = new ArrayList<>();

I am inserting the above list inside a JSON called Data.

Map<String, AttributeValue> valueMap = new HashMap<>();
valueMap.put(":v", new AttributeValue().withS(String.valueOf(dataList)));

Map<String, String> nameMap = new HashMap<>();
nameMap.put("#list", "Data.list");

DynamoDBQueryExpression<> queryExpression = new DynamoDBQueryExpression<>()
                .withFilterExpression("contains(#list, :v)")
                .withExpressionAttributeNames(nameMap)
                .withExpressionAttributeValues(valueMap)
                .withConsistentRead(false);

I used the above approach but it is not working. What I need is I need to filter data if any of the list values contains in the dynamo db inserted list values. The list data is inside Json. So what I am doing wrong here? can anybody help me? Thanks in advance.

Abraham Arnold
  • 301
  • 4
  • 20

1 Answers1

1
  1. Your query doesn't has the withKeyConditionExpression as part of building DynamoDBQueryExpression.
  2. FilterExpression is not improving your RCUs consumption. It adds very little value. I prefer having clean query objects ( ddbMapper.query(Object) ) and filtering post getting response.

From the docs -

A filter expression is applied after a Query finishes, but before the results are returned. Therefore, a Query consumes the same amount of read capacity, regardless of whether a filter expression is present.

Note: If still looking to do it in DynamoDB query, you need to ensure that AttributeValue type provided is correct.

From the docs -

An attribute of type String Set. For example:
"SS": ["Giraffe", "Hippo" ,"Zebra"]
Type: Array of strings

So, here change from new AttributeValue().withS to new AttributeValue().withSS to apply over list. Note that, you will still need to bring your object down to AttributeValue granularity which DDB understands.

This doc has more advanced samples.

  • Actually I have `withKeyConditionExpression` but I didn't add here that. I still needs to go through with `FilterExpression` and I need to know how to solve the `contains()` function. – Abraham Arnold Jan 26 '21 at 19:49
  • 1
    @AbrahamArnold Can you paste how `String.valueOf(dataList)` looks like ? – Anshul Saraswat Kaul Jan 26 '21 at 20:54
  • @AbrahamArnold Let us know if this helped :) – Anshul Saraswat Kaul Jan 27 '21 at 10:54
  • Thank you for the answer. But did you check this? `nameMap.put("#list", "Data.list");` List is inside Data column as a JSON. – Abraham Arnold Jan 28 '21 at 07:41
  • 1
    As can be seen from example pasted above, JSON is not accepted in the query. Did you check this - `"SS": ["Giraffe", "Hippo" ,"Zebra"]` ? – Anshul Saraswat Kaul Jan 28 '21 at 09:28
  • Thank you for helping me. I will check it let you know. By the way so when I am using `dynamoDBMapper.query()` so it is giving me a list of data. Is it always gives `1MB` of data and do I need to iterate every time to get all the data? – Abraham Arnold Jan 30 '21 at 18:05
  • 2
    @AbrahamArnold A single query will at max fetch you 1MB of data. It will load data lazily for you, as and when you go to next element in your list while you are iterating. However, it comes with much higher network cost. In order to get all data at once, you can do - list.size(). It will fetch all the elements at once. – Anshul Saraswat Kaul Feb 01 '21 at 03:26
  • 1
    I am glad I was able to help :) Would highly appreciate accepting and up-voting my answer in that case. – Anshul Saraswat Kaul Feb 01 '21 at 03:28
  • 1
    Thank you very very much for the answer and the clarifications. I got all the things you said. Appreciate putting your time and effort to answer this question. – Abraham Arnold Feb 02 '21 at 12:15
  • 1
    Happy to know that. Much appreciated! – Anshul Saraswat Kaul Feb 03 '21 at 14:06