简体   繁体   中英

DynamoDB filterexpression using Contains on a document

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM