Querying DynamoDB with node.js between values - javascript

Querying dynamoDB table with node.js. The DynamoDB table has key of Timestamp, represented by an integer. In this case, I left :timestampStart as 1 and timestampEnd as 10 as an example.
var params = {
TableName: "Table2",
KeyConditionExpression:"Timestamp = :ts BETWEEN :timestampStart AND :timestampEnd",
ExpressionAttributeValues: {
":ts":"Timestamp",
":timestampStart": 1,
":timestampEnd": 10
}
};
The :ts is not correct, I can see this. I want to return any rows found with a Timestamp value between timestampStart and timestampEnd.
Error message:
"errorMessage": "Invalid KeyConditionExpression: Syntax error;
token: \"BETWEEN\", near: \":ts BETWEEN :timestampStart\"",

If Timestamp is the partition key and not the sort key. Then, you have two problems:
In a Query operation, you cannot perform a comparison test (<, >, BETWEEN, ...) on the partition key. The condition must perform an equality test (=) on a single partition key value and, optionally, one of several comparison tests on a single sort key value. For example:
KeyConditionExpression: 'HashKey = :hkey and RangeKey > :rkey'
You have a syntax error in your KeyConditionExpression, obviously. Keep in mind that Timestamp is a reserved word in DynamoDB. So, you'll have to use ExpressionAttributeNames for that:
(Assuming you have an Id partition key and Timestamp sort key)
var params = {
TableName: "Table2",
KeyConditionExpression: "Id = :id AND #DocTimestamp BETWEEN :start AND :end",
ExpressionAttributeNames: {
'#DocTimestamp': 'Timestamp'
},
ExpressionAttributeValues: {
":id": "SOME VALUE",
":start": 1,
":end": 10
}
};

Related

how to query dynamodb GSI with multiple operators

Lets say i have an entity with this model:
{
id: 'apples',
createdAt: 'some date'
rate: 430,
side: 'SELL',
status: 'OPEN',
GSI1: 'SELL#OPEN#430'
GSI2: 'apples'
}
i want to query using the GSI attributes of GSI2 beign the hash and GSI1 being the range.
The query im looking for is get all apples(GSI2) where GSI1 begins with SELL#OPEN and >= SELL#OPEN#430 so basically im trying to get all apples being sold for 430 or greater and are open.
Please how do i go about this using dynamodb query?
what i have done is:
params = {
TableName: process.env.ORDERS_TABLE_NAME,
IndexName: "GSI2_GSI1",
KeyConditionExpression: `GSI2 = :item and ((begins_with(GSI2, :sideStatus) and >= :baseRate)`,
ExpressionAttributeValues: {
":item": `apple`,
":baseRate": `SELL#OPEN#${rate}`,
":sideStatus": "SELL#OPEN",
},
};
thanks
You can only operate on the Key attributes in the key condition expression. These parameters should do what you want because you have all the information in the GSI1 attribute
params = {
TableName: process.env.ORDERS_TABLE_NAME,
IndexName: "GSI2_GSI1",
KeyConditionExpression: 'GSI2 = :item and GSI1 BETWEEN :lower AND :upper',
ExpressionAttributeValues: {
":item": `apple`,
":lower": `SELL#OPEN#430`,
":upper": "SELL#OPEN#999", // you can probably also use "SELL#OPEN$" because $ is the character following # in ascii order
},
};
Note this assumes that your rate in the GSI1 attribute is left padded with 0s. You need the string to be sorted in the same order as the numbers so if the rate is 10 then you need to store SELL#OPEN#010. (Note you might need more leading 0s depending on the maximum rate.)

What is the proper syntax to get() entries where the sort key begins with a substring using AWS.DynamoDB.DocumentClient in NodeJS?

What is the proper syntax to query database entries whose sort key starts with a specific string?
I believe it's something along the lines of
const query_params = {
TableName: 'my_table',
Key: {
my_primary_key: 'a_primary_key_value',
},
FilterExpression: "my_sort_key begins_with :string",
ExpressionAttributeValues: {
":string": "starts_with_substring"
}
};
Followed by a dynamoDb.get(query_params, ..., but that is not quite right. I am getting an ValidationException: The provided key element does not match the schema error.
According to the SDK query documentation, your query params should look like this
{
TableName: "my-table",
KeyConditionExpression: "#pk= :pk And begins_with(#sk, :sk)",
ExpressionAttributeValues: {
":pk": "a_primary_key_value",
":sk": "starts_with_substring"
},
ExpressionAttributeNames: {
"#pk": "my_primary_key",
"#sk": "my_sort_key"
}
}
You'll also need to change dynamoDb.get() to dynamoDb.query().

DynamoDB Update ExpressionAttributeValues

Sample test data:
"suppliers" : [
{
"supplierName": "xxx supplier"
},
{
"supplierName": "zzz supplier"
}
]
Excerpt of UpdateItem Params:
ExpressionAttributeValues:{
":sA" : {L: [event.suppliers]}
// ":sA" : {L: event.suppliers}
}
I encounter "UnexpectedParameter: Unexpected key '0' found in params". I tried changing the formatting of the AttributeValues but I get other errors like "UnexpectedParameter: Unexpected key 'supplierName' found in params".
I need help properly defining a list AttributeValue. Note that the input sample test data may contain x number of supplierName objects and hence defining the keys (ie. '0', '1', etc) in the AttributeValue is also not an option. I also prefer not to use the documentClient version of UpdateItem.
ExpressionAttributeValues is about to set a value to the parameter of the update expression, for example:
dynamoDb.update({
TableName: ...,
Key: ...,
UpdateExpression: 'set suppliers = :suppliers',
ExpressionAttributeValues: {':suppliers': event.suppliers}
}
You have to provide the key to the record and then you can change the suppliers attribute.

How can I query by sort key in AWS DynamoDB?

I have a database of users, and I'd like to return all users with the last name X. I currently have "last" as the sort key for my table. I'm running the following code, but getting a "Query condition missed key schema element" error.
var params = { TableName: 'Patients',
KeyConditionExpression: '#id = :idNum',
ExpressionAttributeNames: {
'#id': 'last'
},
ExpressionAttributeValues: {
':idNum': 'Test'
}
};
docClient.query(params, function(err, data) {
if (err) {
console.error("Unable to query. Error:", JSON.stringify(err, null, 2));
} else {
console.log("Query succeeded.");
res.json(data);
}
});
To query you must provide a partition key, so with your table, as it is, your only option would be to do a Scan (which is expensive and almost never recommended).
However you can easily add Global Secondary Indexes to allow you to use another key as your partition.
In this case you can add a GSI with last as your partition key.
Then you would be able to Query the global secondary index (note the IndexName parameter) by last name.
If you want to go the scan route, however, you'll need to use:
docClient.scan({
TableName: 'Patients',
FilterExpression: '#l = :l',
ExpressionAttributeNames: { '#l': 'last' },
ExpressionAttributeValues: { ':l': 'Test' },
Limit: 1
}, (err, data) => { /* callback */ })
Just remember that using scans can get expensive and put a strain on your table quickly (more detail here)
This is not the way DynamoDB/NoSQL should be used. You either create a GSI as thomasmichaelwallace suggested or have the users lastname as partition key too. You can add "ln_" before all of your last name partitionkeys to separte them from your other partition keys. If you had firstname as partitions before your primary key should look like that now:
partition | sort
fn_hans | ln_zimmer
fn_steve | ln_jobs
ln_zimmer | fn_hans
ln_jobs | fn_steve
Now you can query all partition which start with ln_. And yes you are supposed to have douplicate data in noSql. NoSQL Design has some articles about how to design a dynamoDB table.

DynamoDB FilterExpression with multiple condition javascript

I have a table with partition key and sort key also 2 other columns. I am unable to get items using FilterExpression for multiple conditions with AND in DynamoDB using javaScript AWS SDK. Can anyone provide correct code to retrieve data with multiple conditions in FilterExpression?
My code is as follows:
var params = {
TableName: 'Department',
KeyConditionExpression: '#company = :companyId'
, ExpressionAttributeNames: {
'#company': 'CompanyID',
'#dType': 'DepartmentType',
'#cTime': 'CreatedTime'
}
, ExpressionAttributeValues: {
':companyId': 'Test',
':deptType': dType,
':daysPrior': 1250456879634
},FilterExpression: '#dType = :deptType AND #ts > :daysPrior'
};
There is typo error in the format in your query(after CreatedTime)
To keep it clean, use either double quotes or single quotes but not both.
I have used double quotes, just the way aws sample codes are there.
var params = {
TableName: "Department",
KeyConditionExpression: "#company = :companyId",
ExpressionAttributeNames: {
"#company": "CompanyID",
"#dType": "DepartmentType",
"#cTime": "CreatedTime" //here
},
ExpressionAttributeValues: {
":companyId": "Test",
":deptType": dType,
":daysPrior": 1250456879634
},
FilterExpression: "#dType = :deptType AND #cTime > :daysPrior"
};
In case you need a bit more complex filter expressions to scan or query your DynamoDB table, you could use brackets, for example:
var params = {
TableName: "Department",
...
FilterExpression: "(not (#type <> :type and #company = :company)) or (#timestamp > :timestamp)",
...
};
Note: this example filter expression does not have a particular meaning.

Categories