0

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; 
      }

I tried different methods and it return no items but does not give me an error.

export async function searchGraba({ term }: { term: string }) {
  const pks = await db.send(
    new ScanCommand({
      TableName: "Event",
      IndexName: "id-index",
      FilterExpression: "contains(#id, :id)",
      ExpressionAttributeNames: { "#id": "id" },
      ExpressionAttributeValues: { ":id": { S: term } },
    })
  );
  console.log(pks.Items);
  return pks.Items;
}

My DB client is configured correctly I have ran multiple query commands(without filters) and scan commands. Here is describe-table command from aws cli.

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
    }
}

Here is my my db client configuration.

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 };
4
  • Show me 2 things. 1. How you create your client. 2. The output of DescribeTable command. Commented May 12, 2024 at 7:19
  • @LeeroyHannigan My Client it configured correctly I have tested it with multiple different queries including scancommand. I will update my initial question with the describetable output. Commented May 12, 2024 at 15:05
  • I didn't say anything was wrong with the client, your issue is you're using the wrong syntax for the high level Document client. Commented May 12, 2024 at 15:55
  • @LeeroyHannigan I have updated my table and added a Phrase attribute that has a few sentences for each Item and I want to search if those sentences have a particular word. I can run the desired query using the Explore Items feature, here is the picture now I want to convert it into code. icloud.com/iclouddrive/099grTENqWsZPXThiEAhxe4Aw#EventQuery Also if you can recommend a place to start learning dynamodb with nextjs that would be great. Commented May 13, 2024 at 0:14

1 Answer 1

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; 
      }
Sign up to request clarification or add additional context in comments.

Comments

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.