Im new to DynamoDB and have a table which is "feeds" and partition key is "id" and i have 3 other attributes which are "category", "description", "pubDate".
I want to query the "category" attribute. But it doesn't work, because i can only query the partition key (hashkey), if im right.
Now my query is that which doesnt work;
let category = event.category;
const params = {
Key: {
"category": {
S: category
}
},
TableName: "feeds"
};
dynamodb.getItem(params, function (err, data) {
if (err) {
console.log(err);
callback(err);
}
else {
console.log(data);
callback(null, data);
}
});
How can i make it work? I tried to write a scan query but i couldn't understand the documentation of AWS good.
Edit: I did make it work with the help of Dunedan. Here is the working code,
var params = {
TableName: 'feeds',
IndexName: 'category-index',
KeyConditionExpression: 'category = :category',
ExpressionAttributeValues: {
':category': 'backup',
}
};
var docClient = new AWS.DynamoDB.DocumentClient();
docClient.query(params, function(err, data) {
if (err) callback(err);
else callback(null, data);
});
If your application will regularly query for the category, you should check out Global Secondary Indexes (GSI), which allow you to generate a projection of your data with another key than the original hash key as the key you can use to query.
Scanning and filtering as you suggested doesn't scale very well, as it fetches all data in the table and just filters the results.
Related
I'm trying to query Dynamo DB for person_id between two dates. I have errors with the following code:
Please note that the primary key of the table is (event_id), but I'm not sure how/where to use it?
var params = {
TableName: "tableName",
IndexName: "person_id-event_date-index",
FilterExpression: "#person_id =:person_id",
KeyConditionExpression: "#person_id = :person_id and #event_date BETWEEN :from AND :to",
ExpressionAttributeNames: {
"#person_id": "person_id",
"#event_date": "event_date"
},
ExpressionAttributeValues: {
":person_id": person_id,
":from": start_date,
":to": end_date
}
}
documentClient.query(params, function(err, data) {
if (err) {
console.error("Unable to query. Error:", JSON.stringify(err, null, 2));
callback(new Error(JSON.stringify(err)))
}
else {
callback(null, data);
}
});
Can anyone please check how to make this working?
Many thanks
Short answer, you cannot do that unless the Table has some GSI (Global Secondary Indexes) set up that allow for that sort of query.
When doing a query you must pass a primary key value, you cannot do a query otherwise.
Considering that you want to query based on a different column, not the primary key, you need to see if you have an index defined with
PrimaryKey = person_id and
RangeKey = event_date
If such an index is note defined you may rely on scan, but that's not recommended.
Here is the fix code:
var params = {
TableName: "tableName" ,
IndexName: "person_id-event_date-index",
KeyConditionExpression: "#person_id = :person_id and #event_date BETWEEN :from AND :to",
ExpressionAttributeNames: {
"#person_id": "person_id",
"#event_date": "event_date"
},
ExpressionAttributeValues: {
":person_id": person_id,
":from": start_date,
":to": end_date
}
}
documentClient.query(params, function(err, data) {
if (err) {
console.error("Unable to query. Error:", JSON.stringify(err, null, 2));
callback(new Error(JSON.stringify(err)))
}
else {
callback(null, data);
}
});
}
I am trying to query on my table using only the partition key and ignoring the sort key but I get no items.
My global secondary index looks like this:
And my table looks like this:
And this is my query:
const params = {
ExpressionAttributeValues: {
':app': 'app',
},
IndexName: 'glc-development-gsi1',
KeyConditionExpression: 'sk = :app',
TableName: this.tableName,
};
return new Promise((resolve, reject) => {
this.client.query(params, (err, data) => {
console.log(data);
if (err) {
reject(err);
} else {
resolve(data);
}
});
});
According to all the documentation I've read and the other questions on here, this should work and I can't understand why it doesn't. The scan from my index is also empty.
Finally found my solution. DynamoDB stores data in indexes only when both the partition key and the sort key are defined, so my index was empty all the time. The query was fine.
I have a table with an attribute with name id and of type HASH. I want to get all items from a array of id's.
{
TableName: `MyTable`,
FilterExpression: 'id IN (:id)',
ExpressionAttributeValues: { ':id': ids },
};
What should I do to get all items by my ids?
You can also use DocumentClient and batchGet.
const AWS = require('aws-sdk');
const documentClient = new AWS.DynamoDB.DocumentClient();
let queryParams = {RequestItems: {}};
queryParams.RequestItems['tableName'] = {
Keys: [{'id': 'Value1'}, {'id': 'value2'}],
ProjectionExpression: 'id' //define other fileds that you have Ex: 'id,name'
};
documentClient.batchGet(queryParams, function (err, data) {
if (err) {
console.log('failure:getItemByBatch data from Dynamo error', err);
} else {
console.log('success:getItemByBatch data from Dynamo data');
console.log(data)
}
});
Please use BatchGetItem API to get multiple values from DynamoDB table.
BatchGetItem
Example:-
var dynamodb = new AWS.DynamoDB({maxRetries: 5, retryDelayOptions: {base: 300} });
var table = "Movies";
var year_val = 2015;
var title = "The Big New Movie";
var params = {
"RequestItems" : {
"Movies" : {
"Keys" : [ {
"yearkey" : {N : "2016"},
"title" : {S : "The Big New Movie 1"}
} ]
}
},
"ReturnConsumedCapacity" : "TOTAL"
};
dynamodb.batchGetItem(params, function(err, data) {
if (err) {
console.error("Unable to get item. Error JSON:", JSON.stringify(err,
null, 2));
} else {
console.log("Movie data:", JSON.stringify(data, null, 2));
}
});
Its in C#, below code is to get all items by an array of ids from a dynamodb table having different guid's using BatchGet or CreateBatchGet
string tablename = "AnyTableName"; //table whose data you want to fetch
var BatchRead = ABCContext.Context.CreateBatchGet<ABCTable>(
new DynamoDBOperationConfig
{
OverrideTableName = tablename;
});
foreach(string Id in IdList) // in case you are taking string from input
{
Guid objGuid = Guid.Parse(Id); //parsing string to guid
BatchRead.AddKey(objGuid);
}
await BatchRead.ExecuteAsync();
var result = BatchRead.Results;
// ABCTable is the table modal which is used to create in dynamodb & data you want to fetch
Im trying to get an Item from DynamoDB based on Primary Key but it throws me an exception:
ValidationException: The provided key element does not match the schema
Here is how my table looks:
I'm following a tutorial and here is how I wrote my get:
let params = {
TableName: process.env.CALL_NAVEGATION_HISTORY_TABLE,
Key: {
"Id": requestBody.CallSid
}
}
dynamoDb.get(params, function(err, data) {
if(err){
console.log('Error on dynamodb', err);
callback(null, Helpers.xmlTwimlResponse(twiml));
}
console.log(data);
callback(null, Helpers.xmlTwimlResponse(twiml));
});
What is wrong on my code?
Sometimes the most obvious thing is what we miss right in front of our eyes.
let params = {
TableName: process.env.CALL_NAVEGATION_HISTORY_TABLE,
Key: {
"Id": requestBody.CallSid
}
}
The Key name is case-sensitive. If you change it to 'id' it should work fine.
I am facing some issue with querying data from DynamoDB can any one of you help me on this? I am coding in NodeJS.
My table looks like below with,
Primary key: RequestId
Secondary index: Userid with sortkey Timestamp
When I am pulling the data using UserId, I am getting lot's for records so, planning to pull the data with Timestamp condition.
RequestId Request Timestamp UserId
var doc = require("dynamodb-doc");
var dynamo = new doc.DynamoDB();
var userid_col = "amzn1.ask.account.AGCAPY7JBHQWHTNGAHJJ";
var databaserec = { TableName: "dna_cdknow_prod_historylog",
IndexName: "UserId-TimeStamp-index",
KeyConditionExpression: "UserId = :input",
FilterExpression : 'created between :val1 and :val2',
ExpressionAttributeValues:{ ":input": userid_col, ":val1" : "2016-05-23T00:00:00Z", ":val2" : "2017-05-23T16:20:49Z" } };
The below code should work if the GSI definition is as follows:-
UserId - Partition key of GSI
created - Sort key of GSI
Corrected code:-
var databaserec = {
TableName: "dna_cdknow_prod_historylog",
IndexName: "UserId-TimeStamp-index",
KeyConditionExpression: "UserId = :input AND created between :val1 and :val2'",
ExpressionAttributeValues:{ ":input": userid_col, ":val1" : "2016-05-23T00:00:00Z", ":val2" : "2017-05-23T16:20:49Z" }
};
docClient.query(databaserec, function(err, data) {
if (err) {
console.error("Unable to query. Error:", JSON.stringify(err, null, 2));
} else {
console.log(params);
console.log("Query succeeded.");
data.Items.forEach(function(item) {
console.log("Item :" + JSON.stringify(item));
});
}
});