How to Filter Nested Array Object in DynamoDB

Narayanan Ramanathan picture Narayanan Ramanathan · Nov 14, 2017 · Viewed 8.9k times · Source

I am very beginner to AWS DynamoDB, I want to scan the DynamoDB with SENDTO.emailAddress = "[email protected]" as FilterExpression.

The DB Structure looks like this

{
    ID
    NAME
    MESSAGE
    SENDTO[
        {
            name
            emailAddress
        }
    ]
}

A Sample Data

{
    ID: 1,
    NAME: "HELLO",
    MESSAGE: "HELLO WORLD!",
    SENDTO: [
        {
            name: "First",
            emailAddress: "[email protected]"
        },
        {
            name: "Second",
            emailAddress: "[email protected]"
        }
    ]
}

I want to retrieve document that match emailAddress. I tried to scan with filter expression and here is my code to retrieve the data. I am using AWS Javascript SDK.

let params = {
    TableName : "email",
    FilterExpression: "SENDTO.emailAddress = :emailAddress",
    ExpressionAttributeValues: {
        ":emailAddress": "[email protected]",
    }
}

let result = await ctx.docClient.scan(params).promise();

Answer

notionquest picture notionquest · Nov 15, 2017

In order to find the item by sendto attribute, you need to know both name and emailAddress attribute value. DynamoDB can't find the data by just one of the attributes in an object (i.e. email attribute value alone).

CONTAINS function can be used to find the data in List data type.

CONTAINS is supported for lists: When evaluating "a CONTAINS b", "a" can be a list; however, "b" cannot be a set, a map, or a list.

Sample code using Contains:-

var params = {
    TableName: "email",
    FilterExpression: "contains (SENDTO, :sendToVal)",
    ExpressionAttributeValues: {
        ":sendToVal": {
            "name" : "First",
            "emailAddress" : "[email protected]"
        }
    }
}; 

If you don't know the value of name and emailAddress attribute, you may need to remodel the data to fulfill your use case.