DynamoDB Querying using Global Secondary Index - amazon-dynamodb

I'm trying to query all the rows which are created the last one week. I have created an index for created key in AWS console. In my query, I added the Key Condition with ComparisonOperator.GT for the created key. But When I run the query it throws an error like Query key condition not supported. If I give the condition as ComparisonOperator.EQ, it will return a single row. But not working for the ComparisonOperator.GT.
Code :
Condition rangeKeyCondition = new Condition();
rangeKeyCondition.withComparisonOperator(ComparisonOperator.GT).withAttributeValueList(new AttributeValue().withS("11:26 23/10/2018 "));
Map<String, Condition> keyConditions = new HashMap<String, Condition>();
keyConditions.put("created", rangeKeyCondition);
QueryRequest queryRequest = new QueryRequest();
queryRequest.withTableName(getTableName(TABLE_NAME));
queryRequest.withIndexName("created-index");
queryRequest.withKeyConditions(keyConditions);
QueryResult result = EventStoreInitializer.getAmazonDynamoDBClient().query(queryRequest);

I have read your case so for your desired output you should not create 'created' as Index bz it becomes key for the table and in keyCondition you can't use GT and LT operator.
you need to use FilterExpression and there you can use GT and LT for the 'created' field.

Related

get all data from dynamo db table without supplying any PK

I am trying to fetch all the data from my dynamodb table but unable to get as all the methods for Query / Scan operates with input parameter. so i tried getting all the rows which having primary key greater than 0.
var table = Table.LoadTable(client,Utilities.Utility.EmployeeTable);
ScanFilter filter = new ScanFilter();
filter.AddCondition("iemp_id", ScanOperator.GreaterThan, 0);
ScanOperationConfig config = new ScanOperationConfig()
{
Filter = filter,
// Optional parameters.
Select = SelectValues.SpecificAttributes,
AttributesToGet = new List<string> { "iemp_id", "demp_salary", "semp_name" }
//ConsistentRead = true
};
Search search = table.Scan(config);`
Here i am getting search.Matches = 0 where it should return data from my table.
You have only two options
1.Query : You need to supply Partition Key(mandatory) and optionally Range key.
2.Scan: Full scan of the table with out Partition key/Range Key.
In your case you will have to do full scan of the table.
DynamoDBQScanExpression scanExpression = new DynamoDBScanExpression();
scanExpression .withFilterExpression(filterexpression)
.withExpressionAttributeValues(expression values);

When to use Map and SqlParameterSource in namedParameterJdbcTemplate?

String SQL = "INSERT INTO Employee (name, age, salary) VALUES (:name,:age,:salary)";
Map namedParameters = new HashMap();
namedParameters.put("name", name);
namedParameters.put("age", age);
namedParameters.put("salary", salary);
namedParameterJdbcTemplate.update(SQL, namedParameters);
String SQL = "UPDATE Employee SET age = :age WHERE empid = :empid";
SqlParameterSource namedParameters = new MapSqlParameterSource();
namedParameters.addValue("age", age);
namedParameters.addValue("empid", empid);
namedParameterJdbcTemplate.update(SQL, namedParameters);
Seems both Map and SqlParameterSource are same. But why did API developers added these API's ? Is there any particular scenario to use Map or SqlParameterSource which makes execution faster? Please explain me clearly. Thanks in advance.
Using a Map is fine for simple cases, but there are two benefits to using SqlParamaterSource over a Map.
The first is simply the builder pattern allowing you to add multiple values inline (namedParameters.addValue().addValue().addValue() etc).
The second is more powerful. The jdbcTemplate will auto-determine the sqlType of your map values while the SqlParamaterSource allows you to explicitly use the sqlType of your choice. This can be an issue depending on your database, indexes and parameters.
An example would be Integers and Longs with an Oracle database. The jdbc template will add these objects to your query with surrounding quotes '' making them effectively strings in your database query. If you have a number in your database with leading 0's it will not be found because '0XXXX' will not match 'XXXX'. If you pass in the right sqlType, the jdbc template will do a number comparison without quotes so XXXX will equal XXXX.
When my place holder values were of different datatypes, this (MapSqlParameterSource) really helped me:
String SQL = "UPDATE Employee SET joindate = :joinDate WHERE empid = :empid";
MapSqlParameterSource namedParameters = new MapSqlParameterSource();
namedParameters.addValue("date", joinDate, Types.Date);
namedParameters.addValue("empid", empid, Types.Integer);
namedParameterJdbcTemplate.update(SQL, namedParameters);

nature of SELECT query in MVC and LINQ TO SQL

i am bit confused by the nature and working of query , I tried to access database which contains each name more than once having same EMPid so when i accessed it in my DROP DOWN LIST then same repetition was in there too so i tried to remove repetition by putting DISTINCT in query but that didn't work but later i modified it another way and that worked but WHY THAT WORKED, I DON'T UNDERSTAND ?
QUERY THAT DIDN'T WORK
var names = (from n in DataContext.EmployeeAtds select n).Distinct();
QUERY THAT WORKED of which i don't know how ?
var names = (from n in DataContext.EmployeeAtds select new {n.EmplID, n.EmplName}).Distinct();
why 2nd worked exactly like i wanted (picking each name 1 time)
i'm using mvc 3 and linq to sql and i am newbie.
Both queries are different. I am explaining you both query in SQL that will help you in understanding both queries.
Your first query is:
var names = (from n in DataContext.EmployeeAtds select n).Distinct();
SQL:-
SELECT DISTINCT [t0].[EmplID], [t0].[EmplName], [t0].[Dept]
FROM [EmployeeAtd] AS [t0]
Your second query is:
(from n in EmployeeAtds select new {n.EmplID, n.EmplName}).Distinct()
SQL:-
SELECT DISTINCT [t0].[EmplID], [t0].[EmplName] FROM [EmployeeAtd] AS
[t0]
Now you can see SQL query for both queries. First query is showing that you are implementing Distinct on all columns of table but in second query you are implementing distinct only on required columns so it is giving you desired result.
As per Scott Allen's Explanation
var names = (from n in DataContext.EmployeeAtds select n).Distinct();
The docs for Distinct are clear – the method uses the default equality comparer to test for equality, and the default comparer sees 4 distinct object references. One way to get around this would be to use the overloaded version of Distinct that accepts a custom IEqualityComparer.
var names = (from n in DataContext.EmployeeAtds select new {n.EmplID, n.EmplName}).Distinct();
Turns out the C# compiler overrides Equals and GetHashCode for anonymous types. The implementation of the two overridden methods uses all the public properties on the type to compute an object's hash code and test for equality. If two objects of the same anonymous type have all the same values for their properties – the objects are equal. This is a safe strategy since anonymously typed objects are essentially immutable (all the properties are read-only).
Try this:
var names = DataContext.EmployeeAtds.Select(x => x.EmplName).Distinct().ToList();
Update:
var names = DataContext.EmployeeAtds
.GroupBy(x => x.EmplID)
.Select(g => new { EmplID = g.Key, EmplName = g.FirstOrDefault().EmplName })
.ToList();

how to pass local variable to a linq query

I have the following code in which I am passing a local variable to a linq query for a specific record, after that record I want to check whether there is a record according to that id or not.
First it gives me the error "Cannot implicitly convert type int to bool"
Second if I want to count the rows in this query or want to check whether there is a row or not, how will I do that, here is my code:
int J_Job_ID = Convert.ToInt32(Request.QueryString["J_Job_ID"]);
//Check If this ID exists in the database
var query = from m in JE.J_Posted_Jobs_Tbl
where m.J_Job_ID = Convert.ToInt32(J_Job_ID)
select m;
it should be
where m.J_Job_ID == Convert.ToInt32(J_Job_ID)
as for count
query.Count()

select single or multiple records using a single linq query

I want to pass a valid id or -1("ALL") from a drop down to the function.
Can I select 'All' rows or one row based on the selected option from ddl from a table using a single linq query?
You can add an OR to the statement to get the result. Basically, (#value = -1) OR (id = #value). Whenever value is -1, it will return all value, otherwise that we be false and only return the matching record.
Having an OR in the LINQ can sometimes result in full-table scans and non-optimal retrievals.
Instead of having a condition inside your LINQ statement, I'd recommend building your LINQ query conditionally based on whether you want a single result or "all":
// Initialize your select
var query = db.Select(r => r);
// Conditionally add the "where"
if (selectedValue != -1)
query = query.Where(n => n.id == selectedValue);
// Collect your results
foreach (var record in query)
{
// ...
}
If you want all records, then your query won't include a where clause at all, otherwise, the where clause will include only the filter by id.

Resources