Home > OS >  DynamoDB filterexpression using Contains on a document
DynamoDB filterexpression using Contains on a document

Time:12-22

I am using Java AWS SDK for AWS dynamoDB. Is it possible to use "Contains" function on a document object? Contains is working on an simple field. but if the field is a @DynamoDBDocument, it is not working. Please let me know if you know of a way to search for a value in a document. My query looks like this:

DynamoDBQueryExpression<SSRequest> query = new DynamoDBQueryExpression<SSRequest>()
            .withHashKeyValues(ssRequest)
            .withIndexName("ssRequestType-index")
            .withFilterExpression(" contains(attachments, :val) ")
            .withExpressionAttributeValues(eav)
            .withConsistentRead(false);

In the above query, attachments is a document. I tried with scan as well. but both scan and query are not working on document fields.

CodePudding user response:

You did not share the structure of your data, but i'll try sum it up:

{
  "id": "1",
  "val": {
    "ABCLink": [
      {
        "DEFName": "MyDefName1",
        "DEFArn": "DEFArn1"
      },
      {
        "DEFName": "MyDefName2",
        "DEFArn": "DEFArn2"
      }
    ],
    "ABCArn": "ProfileArn1"
  }
}

Now lets imagine you want all the items where id=1 and val contains DEFArn1

In order to achieve this you have two options:

  1. You pass the entire map as a condition, meaning you must know both DEFArn and DEFName
    response = client.scan(
        TableName=table_name,
        FilterExpression='contains(#a.#b, :r)',
        ExpressionAttributeValues={
            ':r': {
                "M": {
                    "DEFName": {
                        "S": "MyDefName1"
                    },
                    "DEFArn": {
                        "S": "DEFArn1"
                    }
                }
            }
        },
        ExpressionAttributeNames={
            '#a': 'val',
            '#b': 'ABCLink',
        }
    )
  1. You do not know the full map, but you know the position it should be in the list:
    response = client.scan(
        TableName=table_name,
        FilterExpression='contains(#a.#b[0].DEFArn, :r)',
        ExpressionAttributeValues={
            ':r': {
                "S": "DEFArn1"     
            }
        },
        ExpressionAttributeNames={
            '#a': 'val',
            '#b': 'ABCLink',
        }
    )

NOTE: I've reused an example I shared before, and the code is Boto3, but the logic remains the same. I hope it helps your use-case.

  • Related