DynamoDB ScanCommand with filters

0

Hello,

I am very new to DynamoDB and need help with adding following query to my code. Here is what I have but its giving me an exception error.

ValidationException: One or more parameter values were invalid: ComparisonOperator CONTAINS is not valid for M AttributeValue type

My Code: export async function searchGraba({ term }: { term: string }) { const pks = await db.send( new ScanCommand({ TableName: "Event", IndexName: "id-index", ScanFilter: { id: { ComparisonOperator: "CONTAINS", AttributeValueList: [{ S: term }], }, }, }) ); console.log(pks.Items); return pks.Items; } Enter image description here

Here is my DB configure:

import { DynamoDB } from "@aws-sdk/client-dynamodb";
import { DynamoDBDocument } from "@aws-sdk/lib-dynamodb";

const awsCredetnials = {
  accessKeyId: process.env.AWS_ACCOUNT_ACCESS_KEY,
  secretAccessKey: process.env.AWS_ACCOUNT_SECRET_KEY,
};

const dynamoConfig = {
  region: process.env.AWS_ACCOUNT_REGION,
  credentials: awsCredetnials,
} as {
  credentials: {
    accessKeyId: string;
    secretAccessKey: string;
  };
  region: string;
};

const db = DynamoDBDocument.from(new DynamoDB(dynamoConfig), {
  marshallOptions: {
    convertEmptyValues: true,
    removeUndefinedValues: true,
    convertClassInstanceToMap: false,
  },
});

export { db };

Describe-table:

aws dynamodb describe-table \
    --table-name Event
{
    "Table": {
        "AttributeDefinitions": [
            {
                "AttributeName": "Phone",
                "AttributeType": "S"
            },
            {
                "AttributeName": "id",
                "AttributeType": "S"
            }
        ],
        "TableName": "Event",
        "KeySchema": [
            {
                "AttributeName": "id",
                "KeyType": "HASH"
            }
        ],
        "TableStatus": "ACTIVE",
        "CreationDateTime": "2024-03-11T02:20:20.600000+00:00",
        "ProvisionedThroughput": {
            "LastDecreaseDateTime": "2024-03-11T02:32:19.941000+00:00",
            "NumberOfDecreasesToday": 0,
            "ReadCapacityUnits": 1,
            "WriteCapacityUnits": 1
        },
        "TableSizeBytes": 100,
        "ItemCount": 3,
        "TableArn": "arn:aws:dynamodb:ca-central-1:300485252224:table/Event",
        "TableId": "f1472d40-37c0-4405-a7c5-b5bac836a2ff",
        "GlobalSecondaryIndexes": [
            {
                "IndexName": "PhoneNumberIndex",
                "KeySchema": [
                    {
                        "AttributeName": "Phone",
                        "KeyType": "HASH"
                    }
                ],
                "Projection": {
                    "ProjectionType": "ALL"
                },
                "IndexStatus": "ACTIVE",
                "ProvisionedThroughput": {
                    "NumberOfDecreasesToday": 0,
                    "ReadCapacityUnits": 1,
                    "WriteCapacityUnits": 1
                },
                "IndexSizeBytes": 100,
                "ItemCount": 3,
                "IndexArn": "arn:aws:dynamodb:ca-central-1:300485252224:table/Event/index/PhoneNumberIndex"
            },
            {
                "IndexName": "id-index",
                "KeySchema": [
                    {
                        "AttributeName": "id",
                        "KeyType": "HASH"
                    }
                ],
                "Projection": {
                    "ProjectionType": "ALL"
                },
                "IndexStatus": "ACTIVE",
                "ProvisionedThroughput": {
                    "NumberOfDecreasesToday": 0,
                    "ReadCapacityUnits": 1,
                    "WriteCapacityUnits": 1
                },
                "IndexSizeBytes": 100,
                "ItemCount": 3,
                "IndexArn": "arn:aws:dynamodb:ca-central-1:300485252224:table/Event/index/id-index"
            }
        ],
        "TableClassSummary": {
            "TableClass": "STANDARD"
        },
        "DeletionProtectionEnabled": false
    }
}
jarvis
asked 11 days ago534 views
1 Answer
0

You have an index with id as your partition key, you should not scan with filter, that's inefficient. You should use Query:

export async function searchGraba({ term }: { term: string }) { 
        const pks = await db.send( 
          new Query({ 
            TableName: "Event", 
            IndexName: "id-index", 
            KeyConditionExpression: `id = ${term}`,
          })); 
          console.log(pks.Items); 
          return pks.Items; 
      }

Given the fact you're trying to do a contains, you cannot filter a key so if you want to know if Id contains a value, you need to do so from a table or index that does not have it as partition key:

export async function searchGraba({ term }: { term: string }) { 
        const pks = await db.send( 
          new ScanCommand({ 
            TableName: "Event", 
            FilterExpression: `contains(id, ${term})`
          })); 
          console.log(pks.Items); 
          return pks.Items; 
      }
profile pictureAWS
EXPERT
answered 11 days ago
  • This solution did not work. I will update my code with my db configuration and describe-table command from cli.

  • It didn't work as you are trying to do a contains on an indexes key, which you cannot do. Updated my answer.

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.

Guidelines for Answering Questions