How to write a query in dynamo db with a conditioned expression - node.js

I want to query a dynamo db table for getting company id but the same table need a hash key so my query is something like this.
var optsq = {
'ConsistentRead': true,
'AttributesToGet': ['companyid'],
TableName : usertable,
Key : {
"userid" : {
"S" : usrname
},
"comapnyid" :{
"S":''
}
}
};
My query will only work if the query has the value of company id as well but i want to get company id how can i achive this. In my node js
dynamodb.getItem(optsq, function(err, compdata) {
if(err){
console.log(err);
}else{
console.log(compdata);
}

Instead of getItem, you should do a query, which allows you to specify only the userId.
var optsq = {
'ConsistentRead': true,
TableName : usertable,
KeyConditionExpression: "userid = :userid",
ExpressionAttributeValues: { ":userid": usrname },
ProjectionExpression: "companyid" }

Related

dynamodb get all items by an array of ids

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

DynamoDB scanning using filter

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.

How to fetch data from dynamodb with Keycondition expression with sort key timestamp?

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));
});
}
});

How to query a table by using IN conditions in DynamoDB

Struggling to find an example of how to query a table to return rows with ids from a given list.
The query below throws on the inclusion of IN
var params = {
id: '7deb3df9-552b-47a4-aef3-ad601f141d50'
};
var p = {
TableName: 'players',
KeyConditionExpression: 'id IN (:id)',
ExpressionAttributeValues: buildQuery(params)
};
You can't use "IN" operator with KeyConditionExpression, please see details in this SO question
You may want to use batchGetItem instead of query, which is not so efficient though.
Here is how your params could look like:
var params = {
RequestItems: {
'players': {
Keys: [{
id: "7deb3df9-552b-47a4-aef3-ad601f141d50",
rangeKey: "<range key 1>" // <--- if your table has a range key, you must specify its value here
}, {
id: "<ANOTHER ID 2>",
rangeKey: "<range key 2>"
}, {
id: "<ANOTHER ID 3>",
rangeKey: "<range key 3>"
}]
}
}
};
dynamodbDoc.batchGet(params, function(err, data) {
});

Sequelize "SELECT * from tablename" query

Why the query below executes SELECT id, email, name FROM users AS users WHERE users.email = 'admin#admin.com'; rather than SELECT * from users WHERE email = admin#admin.com ?
http://docs.sequelizejs.com/en/latest/docs/querying/#where
Documentation states that it'll run a SELECT * query when I do findAll(), but it does something different in my example. What's missing here?
Here's my users model.
var user = sequelize.define('users', {
id : {
type : Sequelize.INTEGER,
primaryKey : true,
autoIncrement : true
},
email : {
type : Sequelize.STRING
},
name : {
type : Sequelize.STRING
}
},
{
tableName: 'users',
freezeTableName: true
});
And this is my query. It seems that it only selects defined columns, but I don't want this.
var email = "admin#admin.com";
user.findAll({where: {email: email}}).then(function (user) {
res.send(user);
}).error(function (err) {
console.log("Error:" + err);
});
This is expected behavior of sequelize selecting only the columns which you have defined. If you want to select all of the columns using sequelize you must define them in your model.

Resources