node.jsamazon-dynamodbdynamodb-queriesdynamo-local

Dynamo DB advice on structure of table


I'm wanting to store data like this

{ date: '2020-10-06T20:46:01.942Z', topic: 'a great topic', votes: 123 },
{ date: '2020-10-07T23:46:01.942Z', topic: 'a great topic', votes: 125 },
{ date: '2020-10-06T20:46:03.942Z', topic: 'a not so great topic', votes: 12 }

I've created a Dynamo and have my timestamp as the primary key, due to low traffic it's safe to assume these will be unique.

I'm hoping to return data based on topic so a dynamo query using the sort key where it equals a great topic.

I keep getting "message": "Query condition missed key schema element" when using the following in a dyanmo db query statement:

params = {
    TableName: table,
    KeyConditionExpression: "#topic = :topic",
    ExpressionAttributeNames:{
        "#topic": "topic"
    },
    ExpressionAttributeValues: {
        ":topic": "a great topic"
    }
  }

This is my table

var tableParams = {
    TableName : "a cool table",
    KeySchema: [       
        { AttributeName: "date", KeyType: "HASH"},  //Partition key
        {
          AttributeName: "topic",
          KeyType: "RANGE"
      }
    ],
    AttributeDefinitions: [       
        { AttributeName: "date", AttributeType: "S" },
        { AttributeName: "topic", AttributeType: "S" }
    ],
    ProvisionedThroughput: {       
        ReadCapacityUnits: 5, 
        WriteCapacityUnits: 5
    }
};

I'm hesitant to use scan because it can be quite wasteful even though it would be easier to filter the data using javascript :p

Thanks for your help.


Solution

  • You are attempting to query your table using the topic field, which won't work because it's your sort key. When querying DynamoDB, you need to provide the partition key with the optional sort key.

    Let's quickly review some terminology so we are all on the same page (from the docs).

    When you perform a query operation in Dynamodb, you use the KeyConditionExpression parameter to provide a specific value for the partition key. The Query operation will return all of the items from the table or index with that partition key value. You can optionally narrow the scope of the Query operation by specifying a sort key value and a comparison operator in KeyConditionExpression

    Looking at your query, you're trying to query an item by specifying only the sort key, which is not going to work. I think you've got your primary key backwards. You want the partition key to be topic and your sort key to be date.

    To get your query to work as written, change the KeySchema of your table to this:

        KeySchema: [       
            { AttributeName: "topic", KeyType: "HASH"},
            { AttributeName: "date", KeyType: "RANGE"}
        ]
    

    If you did this, your query operation would return the items for that topic sorted by date.