2

I'm trying to query a DynamoDB table using a Global Secondary Index with an HashKey and a RangeKey.

I want to QUERY the IndexCustomerId by CustomerId and DateTime range (from-to). There's no option to set the Index RangeKey as a DateTime. The only choices are: String, Number and Binary.

I'm using C# Object Persistence Model Amazon.DynamoDBv2.DataModel API on .NET Framework v3.5.

Table:

+-------------------+----------+---------------------------+----------------+------------+
| InputFlowCode     |  Counter |  OrderIssueDate           |  OrderTypeCode | CustomerId |
+-------------------+----------+---------------------------+----------------+------------+
| bac9-35df6ac533fc |  000004  |  2016-07-19T22:00:00.000Z | 220            | 123        |
+-------------------+----------+---------------------------+----------------+------------+
| a3db-9d6f56a5c611 |  000006  |  2016-06-30T22:00:00.000Z | 220            | 456        |
+-------------------+----------+---------------------------+----------------+------------+
| af1c-db5b089c1e32 |  000010  |  2016-07-02T22:00:00.000Z | 220            | 789        |
+-------------------+----------+---------------------------+----------------+------------+
| ...               | ...      | ...                       | ...            | ...        |
+-------------------+----------+---------------------------+----------------+------------+

Global Secondary Index definition:

IndexCustomerId:
- CustomerId (integer), 
- OrderIssueDate (DateTime on model, but string on Index definition)

Code:

try
{
    DateTime dateFrom = new DateTime(2016, 08, 01);
    DateTime dateTo = new DateTime(2016, 08, 15);

    List<MyDynamoDBItem> items = new List<MyDynamoDBItem>();

    DynamoDBOperationConfig operationConfig = new DynamoDBOperationConfig();
    operationConfig.OverrideTableName = "Transactions";
    operationConfig.IndexName = "IndexCustomerId";

    DynamoDBContext context = new DynamoDBContext(DynamoDBClient);

    // 1) Works
    items = context.Query<MyDynamoDBItem>(customerId, operationConfig).OrderByDescending(o => o.OrderIssueDate).ToList();

    // 2) Doesn't work
    items = context.Query<MyDynamoDBItem>(customerId, QueryOperator.Between, dateFrom, dateTo, operationConfig).OrderByDescending(o => o.OrderIssueDate).ToList();

    // 3) Works, but I don't know if it is the right choice...
    List<ScanCondition> conditions = new List<ScanCondition>();
    conditions.Add(new ScanCondition(PeppolOrdineDynamoDBTableAttributes.OrderIssueDate, ScanOperator.Between, dateFrom, dateTo));
    operationConfig.QueryFilter = conditions;
    items = context.Query<MyDynamoDBItem>(customerId, operationConfig).OrderByDescending(o => o.OrderIssueDate).ToList();
}
catch (Exception)
{
    throw;
}

The first query without parameters works.

The second query with the Between operator and the 2 DateTime throws an Exception:

{"Cannot cast objects of type 'System.Int32' to type 'System.String'."}

The third query that uses QueryFilter that is a List and ScanOperator works too, but I don't know what's the difference with QueryOperator and also if it is the right choice, since I want to make a QUERY and not a SCAN.

1 Answer 1

3

I had the same problem but I was using greaterThan, I found that adding the parameter values into an object array fixed it.

So maybe something like:

items = context.Query<MyDynamoDBItem>(customerId, QueryOperator.Between, new object[] {dateFrom, dateTo}, operationConfig).OrderByDescending(o => o.OrderIssueDate).ToList();
Sign up to request clarification or add additional context in comments.

1 Comment

This thing with the object array really helped me to get my code working. I am scanning for rows having a DateTime.Min value. When providing DateTime.Min as a single parameter the code builds but gives zero hits allways, but with the object array I have seen it working for operators 'Equal' and 'GreaterThan'. It also works for operator BeginsWith. I think this reveals that DateTime do not exist i DynamoDB. The real implementation is just strings.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.