Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Querying DynamoDB without Primary Key

I need to query a DynamoDB table by a key different than its Primary Key. I tried to create a Global Secondary Index for it. However I get this error: "query key condition not supported dynamodb". By seeing some examples, it looks like I can't query by a secondary index unless I also include the primary index/key, is this correct? Let's say I need to query by all employees that work in a certain city, can I do that without the employeeID?

Updated info Maybe my index is not created as it should?

Table info:

  • id-->Primary partition key
  • primary sort key-->name

GSI:

  • Partition Key/primary key--> city
  • Projected-->All

When I query from node I sent as a parameter the city, and the index name:

    const filter = { city: city};     return this.getRecordsFromDb(filter, { IndexName: "myIndexName" })         .then(records => __.head(records)); 
like image 375
joeCarpenter Avatar asked Apr 11 '17 17:04

joeCarpenter


People also ask

Can you Query DynamoDB without primary key?

Hash key in DynamoDB The primary reason for that complexity is that you cannot query DynamoDB without the hash key. So, it's not allowed to query the entire database. That means you cannot do what you would call a full table scan in other databases.

Can you Query in DynamoDB?

In Amazon DynamoDB, you can use either the DynamoDB API, or PartiQL, a SQL-compatible query language, to query an item from a table. With Amazon DynamoDB the Query action lets you retrieve data in a similar fashion. The Query action provides quick, efficient access to the physical locations where the data is stored.

Does DynamoDB have primary key?

There are two types of primary keys in DynamoDB: Partition key: This is a simple primary key. If the table has only a partition key, then no two items can have the same partition key value. Composite primary key: This is a combination of partition key and sort key.

Can I Query by sort key DynamoDB?

You can not query only using a Sort Key. You need to specify a partition key to perform query operations. Else, you need to create a global secondary index or perform a scan operation.


2 Answers

Note:- As you have not provided the full code, it is difficult to simulate and identify the issue. However, I have created the similar tables and indexes. It works fine for me. You can refer the below code for more details.

Here is the table create script and query the index.

You can change the table name and index name if required. I have followed the same key attributes structure that you have mentioned on post.

This has been tested and working fine.

1) Create table 'city' with index 'city_index':-

var params = {         TableName: 'city',         KeySchema: [ // The type of of schema.  Must start with a HASH type, with an optional second RANGE.             { // Required HASH type attribute                 AttributeName: 'id',                 KeyType: 'HASH',             },             { // Required HASH type attribute                 AttributeName: 'name',                 KeyType: 'RANGE',             }                      ],         AttributeDefinitions: [ // The names and types of all primary and index key attributes only             {                 AttributeName: 'id',                 AttributeType: 'S', // (S | N | B) for string, number, binary             },             {                 AttributeName: 'name',                 AttributeType: 'S', // (S | N | B) for string, number, binary             },             {                 AttributeName: 'city',                 AttributeType: 'S', // (S | N | B) for string, number, binary             },          ],         ProvisionedThroughput: { // required provisioned throughput for the table             ReadCapacityUnits: 400,              WriteCapacityUnits: 400,          },         GlobalSecondaryIndexes: [ // optional (list of GlobalSecondaryIndex)             {                  IndexName: 'city_index',                  KeySchema: [                     { // Required HASH type attribute                         AttributeName: 'city',                         KeyType: 'HASH',                     }                 ],                 Projection: { // attributes to project into the index                     ProjectionType: 'ALL' // (ALL | KEYS_ONLY | INCLUDE)                 },                 ProvisionedThroughput: { // throughput to provision to the index                     ReadCapacityUnits: 400,                     WriteCapacityUnits: 400,                 },             },             // ... more global secondary indexes ...         ],      };     dynamodb.createTable(params, function(err, data) {         if (err){ console.log("error :" +JSON.stringify(err));} // an error occurred         else console.log("success :" +JSON.stringify(data)); // successful response      }); 

2) Insert some data to city table

3) Query using index:-

var docClient = new AWS.DynamoDB.DocumentClient(); var table = "city"; var params = {     TableName : table,     IndexName : 'city_index',     KeyConditionExpression : 'city = :cityVal',      ExpressionAttributeValues : {         ':cityVal' : 'london'             } };  docClient.query(params, function(err, data) {     if (err) {         console.error("Unable to read item. Error JSON:", JSON.stringify(err,                 null, 2));     } else {         console.log("GetItem succeeded:", JSON.stringify(data, null, 2));     } }); 
like image 187
notionquest Avatar answered Sep 24 '22 03:09

notionquest


This is my implementation with Node.js (of querying by another field) with scan:

  var params = {     TableName: 'TableName',     FilterExpression: 'AnotherFieldName = :email',     ExpressionAttributeValues: {       ":email": { S: emailISearchFor }       }   };    ddb.scan(params, function(err, data){     if(err){       ...     } else {        if(data.Items.length > 0){ // here is the info         valueIWant = data.Items[0].PrimaryKeyName.S;       }      }    }); 
like image 21
hestellezg Avatar answered Sep 25 '22 03:09

hestellezg