Search code examples
amazon-dynamodbdynamodb-queries

(DynamoDB Collection) Is sortKey required for Collection query?


I'm making some lambdas to get data from a dynamoDB table.

The DynamoDB table has

  • composite primary key
    • 'setId' as partition key (range key) (I used this word 'set' as a noun like 'group' here)
    • 'id' as sort key (hash key)
  • 'type' as GSI
  • and other attributes ('name' and etc)

enter image description here

If I understood correctly,
I can use the setId to query because DynamoDb make collections by partition key.
So I tried with this parameters.

const params = {
        TableName: MY_TABLE_NAME,
        KeyConditionExpression: `#setId = :setId AND #type = :type `,
        ExpressionAttributeNames: { "#setId": "setId", "#type": "type" },
        ExpressionAttributeValues: {
            ":setId": { S: "set_1" },
            ":type": { S: "type A" },
        },
    }

But it returns error

ValidationException: Query condition missed key schema element: id

Q.

  • Is sort key required to get collection?
  • or Did I drop somethings in the parameters?
  • or Do I need to set additional something on the table?

Thanks in advance!



FYI) I tried with GSI also and below worked as I expected..

const params = {
        TableName: MY_TABLE_NAME,
        IndexName: "blahblah",
        KeyConditionExpression: `#type = :type`,
        FilterExpression: `#setId = :setId`,
        ExpressionAttributeNames: { "#setId": "setId", "#type": "type" },
        ExpressionAttributeValues: {
            ":setId": { S: "set_1" },
            ":type": { S: "type A" },
        },
    }

Solution

  • ‎You showed us the request parameters, but not which request you were doing. DynamoDB has two different read requests relevant to your situation - GetItem and Query:

    • The first, GetItem, can only get a single item, and a single item is specified by its full primary key (in your case, setId and id). You cannot use GetItem and only specify part of the primary key. If you did that, you'd see an error similar to what you saw.
    • The second type of request, Query, is probably the one you wanted to use. It can get you all the items that have the same partition key (setId), sorted by the sort key (id) - and you don't need to specify a specific sort key in the query. Please read the documentation how to use Query, and note the results are paged (in theory a query might return millions of items, and cannot do this in a single page).

    Another problem in your request (maybe that's the problem you saw?) is that you tried to to use #type = :type in KeyConditionExpression. You can't - the key condition is, as its name says, is just for the primary key - and type isn't (unless you're querying the GSI). You should put this condition in the FilterExpression, not KeyConditionExpression.