9

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();
3
  • You can fetch data from dynamodb table by using the partition key or the combination of partition key and sort key. On the other hand, you can use indexes. Commented Nov 15, 2017 at 11:05
  • I tried about partition key and sort key it wasn't helpful, I read that this operation is not supported by DynamoDB. We can query an object attribute but not object array attribute. Commented Nov 15, 2017 at 15:47
  • I updated my answer Commented Nov 15, 2017 at 16:16

2 Answers 2

6

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.

Sign up to request clarification or add additional context in comments.

3 Comments

Yeah thanks, I have remodel the data as two separate arrays.
If you keep two separate arrays, how would you associate the name and email address?
This compares the whole object, which can be useful. How do we go about just checking one field of the map?
2

I think that you should create two tables for users and for messages.

The user table has partition_key: user_id and sort_key: email and a field with an array of his messages ids.

The message table has partition_key: message_id and a field with an array of users ids.

When you will get the array of users ids you can use BATCH GET query to get all users of one message.

When you will get the array of message ids you can use BATCH GET query to get all messages of one user.

If you want to get one user by email you can use QUERY method.

Docs

6 Comments

Thanks, I have remodel the data as two separate arrays. But there is no way in DynamoDB to do the above operation.
You should use documentClent for this
I gave you a link
Yeah I used documentClient and tried your solution, it did work but I want to have the data as a single document.
Actually this is a feature of nosql databases. Feel free to create separate tables. It will help to manage throwout capacity for each table and save your money.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.