Dynamodb is it possible to query all values in a column - amazon-dynamodb

I am trying to work out the best method for querying all the values down a column. Should I set it as a GSI (it is currently). is it possible with a query or would I need to to do a scan?
Thanks for your help

You have to do a scan if you are not filtering by key. Here is the sample code to scan the index and get all the values.
List<String> categoryList = new ArrayList<>();
DynamoDB dynamoDB = new DynamoDB(dynamoDBClient);
Table table = dynamoDB.getTable("Music");
Index index = table.getIndex("Secondary Index Name");
ItemCollection<ScanOutcome> items = null;
ScanSpec scanSpec = new ScanSpec().withSelect(Select.SPECIFIC_ATTRIBUTES).withAttributesToGet("Category");
items = index.scan(scanSpec);
Iterator<Item> pageIterator = items.iterator();
while (pageIterator.hasNext() ) {
categoryList.add(pageIterator.next().getString("Category"));
}

Related

DynamoDB Querying using Global Secondary Index

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.

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

Update 2000 records with one query

I have a Database table:
Item
ID (uniqueidentifier)
Index (int)
I have a list of 2000 key-value pairs items where the key is ID and value is Index, which i need to update it. How can i update all the 2000 items from database using one single sql query?
Right now i have something like this:
// this dictionary has 2000 values
Dictionary<Guid, int> values = new Dictionary<Guid,int>();
foreach(KeyValuePair<Guid, int> item in values)
{
_db.Database.ExecuteSqlCommand("UPDATE [Item] SET [Index] = #p0 WHERE [Id] = #p1", item.Value, item.Key);
}
However, i am making too many requests to the SQL Server, and i want to improve this.
Use table value parameters to send those values to SQL Server and update Items table in one shot:
CREATE TYPE KeyValueType AS TABLE
(
[Key] GUID,
[Value] INT
);
CREATE PROCEDURE dbo.usp_UpdateItems
#pairs KeyValueType READONLY
AS
BEGIN
UPDATE I
SET [Index] = P.Value
FROM
[Item] I
INNER JOIN #pairs P ON P.Id = I.Id
END;
GO
If you really need to update in that manner and have no other alternative - the main way around it could be this rather "ugly" technique (and therefore rarely used, but still works pretty well);
Make all 2000 statements in one string, and execute that one string. That makes one call to the database with the 2000 updates in it.
So basically something like this (code not made to actually run, it's an example so t
Dictionary<Guid, int> values = new Dictionary<Guid, int>();
System.Text.StringBuilder sb = new System.Text.StringBuilder();
foreach (KeyValuePair<Guid, int> item in values)
{
sb.Append(String.Format("UPDATE [Item] SET [Index] = {0} WHERE [Id] = '{1}';", item.Value, item.Key));
}
_db.Database.ExecuteSqlCommand(sb.ToString);

how to group a query in linq to Entity

I am using linq to Entity to retrieve data from to different tables by joining them, but I also want to group them by the field problemDesc in order to get rid of unnecessary duplicate entries for the same problem.
here is the code:
using (AssistantEntities context = new AssistantEntities())
{
var problems = context.tblProblems;
var customers = context.tblCustomers;
var query =
from problem in problems
join customer in customers
on problem.CustID equals customer.custID
where problem.IsActive == true
orderby customer.isMonthlyService == true descending
select new
{
problemID = problem.problemID,
ProblemCreateDate = problem.ProblemCreateDate,
CustID = problem.CustID,
name = customer.name,
isMonthlyService = customer.isMonthlyService,
StationName = problem.StationName,
problemDesc = problem.problemDesc,
LogMeIn = problem.LogMeIn
};
return query.ToList();
}
I am doing query.toList() in order to use that list in a gridview as a dataSource.
and if it possible, also add a field that count the duplicate problems.
You have plenty of examples in the following link.
LINQ - Grouping Operators

Use linq to get parent objects based on one of the property in a self referencing table

I have a table called Quiz that have these fields
id As Int
created As DateTime
header As Sring
body As String
fk_parent As int
url As String
All the items without parent key would be the question, and ones that have the parent key would be the answer. I am having the problem to get all the latest active questions (based both on questions created time and and answer created time).
I am struggling to write a Linq query that can do the above task.
Here's a start:
IQueryable<int> keys =
from x in dc.Quiz
let masterID = ParentId.HasValue ? ParentId.Value : Id
group x by masterID into g
order g by g.Max(x => x.created) descending
select g.Key
List<Quiz> = dc.Quiz.Where(x => keys.Take(20).Contains(x.Id)).ToList();
This assumes answers aren't parents of answers... If they can - you have an arbitrary depth tree walk on your hands, which is a wrong shaped nail for Linq and for SQL.
You could try joining the table on itself in LINQ and creating a new object that holds the Questions and answers:
var QandA = from q in tbl
join a in tbl on q.id equals a.fk_parent
select new {
QHeader = q.header,
QBody = q.body,
QUrl = q.url,
AHeader = a.header,
ABody = a.body,
AUrl = a.url
};
I think this is how your table is setup, but I might have the join wrong.

Resources