1

I am currently trying to load info from a dynamo DB table using a LSI and dynamoDB mapper class. Assume i have the following code

Conisder this class

class Employee {
    @DynamoDBHashKey
    public String getID() {
        return ID;
    }
    @DynamoDBRangeKey
    public String getFirstName() {
        return firstName;
    }

    @DynamoDBIndexRangeKey(localSecondaryIndexName = "my-lsi")
    public String getLastName() {
    return lastName;
    }

    public String getMyotherfield() {
    return myotherfield;
    }
}

Consider this piece of code to retrieve info using LSI and dynamoDB mapper

Employee obj = new Employee();
obj.setID("221");
obj.setLastName("SOMEONE");
DynamoDBQueryExpression<Employee> queryExpression = new DynamoDBQueryExpression<>();
queryExpression.setHashKeyValues(obj);
queryExpression.setIndexName("my-lsi");
queryExpression.setProjectionExpression("myotherfield");

PaginatedQueryList<Employee> paginatedQueryList = mapper.query(Employee.class, queryExpression);
Iterator<Employee> iterator = paginatedQueryList.iterator();
while (iterator.hasNext()) {
    Employee pp = iterator.next();
    // some code
}

[EDIT] Is this the right way to query LSI with mapper? If not what is a better way to fetch data from the table using LSI and dynamoDBMapper? (in terms of performance)

i also found this https://java.awsblog.com/post/Tx3GYZEVGO924K4/The-DynamoDBMapper-Local-Secondary-Indexes-and-You but its a 2013 link. I am not able to find latest documentation on querying with LSI and mapper.

jigar surana
  • 1,186
  • 2
  • 8
  • 10
  • what exactly are you looking for when you said "better way"? Is it in terms of performance? In terms of pagination? – Dasharath Aug 24 '16 at 13:25

1 Answers1

2

Note that in the code you have given, you haven't set the range key at all. Use queryExpression.setRangeKeyConditions() to do so.

Here is a code sample:

Map<String, Condition> rangeKeyConditions = new HashMap<>();
rangeKeyConditions.put("lastName", new Condition()
                 .withComparisonOperator(ComparisonOperator.EQ)
                .withAttributeValueList(new AttributeValue().withS("SOMEONE")));
queryExpression.setRangeKeyConditions(rangeKeyConditions);`

[Update]:

It is not sufficient (nor necessary) to set the range key value ("SOMEONE") in the object (obj), since that object is used only for setting the hashKey. Have a look at the examples here

Dasharath
  • 549
  • 4
  • 15
  • I have set the **indexName** in **queryExpression**. Also I have set the **lastName** field in the **obj** . isn't that enough? The current method gives me a solution, but i am not sure if this is the best way of querying using a LSI. (both in terms of performance and getting the right answer) – jigar surana Aug 24 '16 at 16:42
  • is it necessary to use rangeKeyConditions? – jigar surana Aug 24 '16 at 16:45
  • Specifying a range key is optional for DynamoDB queries. In your case, since you want to query based on lastName (which is a range key for my-lsi), the only way to specify this range key is using rangeKeyConditions() method. In terms of getting the right answer, this is the only way. You could also take a look `queryPage()`. The difference between `query` and `queryPage` is explained here : http://stackoverflow.com/a/32800303/2491766 – Dasharath Aug 24 '16 at 17:25