-1

I'm attempting to set up my DynamoDB table so I can query the data via a rest API. My table has a partition key (id) which is a randomly generated ID, a sort key (name) and a List of strings (domain).

I have also set up a global secondary index for the "name" field.

I'm attempting to write a lambda that will search for items using both the name and possible search the domain array also. Is this possible? If so how do I set up the table as I'm currently getting this error:

Query key condition not supported

Here is my Lambda query code:

async function query(tableName, searchTerm) {
  return new Promise((resolve, reject) => {
    const params = {
      IndexName: "nameIndex",
      ExpressionAttributeNames: {
        "#name": "name",
      },
      ExpressionAttributeValues: {
        ":topic": { S: searchTerm },
      },
      KeyConditionExpression: "begins_with(#name, :topic)",
      TableName: tableName,
    };

    ddb.query(params, (err, data) => {
      if (err) {
        reject(err);
      } else {
        console.log("Success", data.Items);
        resolve(data.Items);
      }
    });
  });
}
Kieran Crown
  • 307
  • 5
  • 16
  • If by 'uniquely-generated ID', you mean that every item has a unique `id` value (such as a UUID), then I don't think it makes sense to have `name` as SK. It should just be a regular attribute. Or are there multiple items with the same `id` value? – jarmod Aug 17 '22 at 22:47
  • FYI no need to create your own promises. You can use `const data = await ddb.query(params).promise();` – jarmod Aug 17 '22 at 23:19
  • @jarmod Yeah the IDs are random; I'm just looking for a way to query the names for each row. I thought the name had to be an index to do so. Also thanks for the heads up on the promise situation. – Kieran Crown Aug 18 '22 at 09:03
  • GSI on name would be sufficient. The only value in having an SK is when you have a PK that can actually be used to group values e.g. PK=country, SK=town or PK=user, SK=game. – jarmod Aug 18 '22 at 17:53

1 Answers1

2

A PK must be provided as a value. You can't do expressions like begins with on a PK.

Here are a lot of example programs doing queries with Node:

https://github.com/aws-samples/aws-dynamodb-examples/tree/master/DynamoDB-SDK-Examples/node.js/WorkingWithQueries

hunterhacker
  • 6,378
  • 1
  • 14
  • 11
  • In their query examples, the ID is always known (KeyConditionExpression: '#id = :id and begins_with(#dt, :dt)'). In my case it is not. How can I just search on the name field without knowing the id value? – Kieran Crown Aug 18 '22 at 09:05
  • If name is a string and your GSI has it setup as the PK then you don’t need the id when querying the GSI. – hunterhacker Aug 18 '22 at 14:37
  • If name is a list of strings, you can’t make a list a PK. – hunterhacker Aug 18 '22 at 14:38