Reputation: 915
I am from SQL background and very new to Dynamodb. I have a single table like this:
-----------------------------------------------------------
| dbId | genId | colData | deviceId | updateOn | params |
-----------------------------------------------------------
| | | | | | |
----------------------------------------------------------
Here dbId
is primary key and genId
is sort key. I have created two local secondary indexs in deviceId
and updateOn
. In SQL I can query from the table:
String dbId = "151/2020-21";
int deviceId = 1001;
long updOn = 1608456211308;
String query = "select * from tableName where dbId = '"+dbId+"' and deviceId != "+deviceId+" and updateOn > " + updOn;
In DynamoDb my keyConditionExpression is : dbId = :dbId and updateOn > :updateOn and deviceId != :deviceId
. It gives me error :
DynamoDbException: Invalid KeyConditionExpression: Syntax error; token: "!", near: "deviceId !="
I removed the '!'
to this : dbId = :dbId and updateOn > :updateOn and deviceId = :deviceId
. It gives me error:
DynamoDbException: Conditions can be of length 1 or 2 only
How can I perform my desired query in Dynamodb? How should I design my Dynamodb table (I mean, primary key, indexes etc) so that I get the same sql like result?
Upvotes: 11
Views: 10686
Reputation: 3405
When it comes to query()
in dynamoDb, it is recommended to specify only the partition key and sort key in KeyConditionExpression
.
So if you want to perform the query()
with more conditions, you should consider FilterExpression
. E.g:
const params = {
TableName: 'table-name',
KeyConditionExpression: 'pk = :pk AND sk = :sk',
FilterExpression: 'dbId = :dbId and updateOn > :updateOn and deviceId != :deviceId',
ExpressionAttributeValues: {
':pk': '12345',
':sk': 'lorem-ipsum',
':dbId': '0987654321',
':updateOn': '2022-06-25',
':deviceId': '123',
},
}
const docClient = new AWS.DynamoDB.DocumentClient();
const result = await docClient.query(params).promise();
Upvotes: 17
Reputation: 1401
Now, reason you are facing error 'Conditions can be of length 1 or 2 only' is because you are specifying 3 conditions within KeyConditionExpression. Please specify only partition key and sort key.
Lastly, you don't need to create a LSI for this purpose. You can perform same operation on original table or need to add Global Secondary Index, Which can help you to achieve the query on two conditions only.
As mentioned, the attribute included in "KeyConditionExpression" should be your hash key only, matching your base table schema. If you want to query on all Then this not possible because there will be no sort key in any case as recommended by AWS Doc's.
Upvotes: 10