Reputation: 1033
I have a DynamoDb table called Users. I am trying to execute a very simple query where the user's last name is like 'John*' (Johnson, Johnston, Johnny, etc), however I cannot find a very straight forward example.
Below is a snippet of my code:
public class DynamoDbUsersTest extends ApplicationTest {
@Autowired
private DynamoDb dynamoDb;
private Table usersTable = dynamoDb.getTable("Users");
public void getUsersByLastNameContainsTest(){
//userTable.contains(user.getLastName()); // No such method.
userTable.scan(new ScanFilter("lastName").contains("John");
...
}
}
Can someone please point me in the right direction? I tried looking at the Query
Object, but I'm not sure it'll do what I need it to.
Scan
Object to make this work, however it does a full table scan with each query.
Has anyone found a better/faster way of searching with partial values?
Would the following be faster?
public class DynamoDbUsersTest extends ApplicationTest {
@Autowired
private DynamoDb dynamoDb;
private Table usersTable = dynamoDb.getTable("Users");
public void getUsersByLastNameContainsTest(){
userTable.query(new QueryFilter("lastName").contains("John");
...
}
}
Upvotes: 0
Views: 2302
Reputation: 39226
Here is the ScanSpec
using contains
to match the string partially.
Table table = dynamoDB.getTable("tablename");
Map<String, Object> attributeValueMap = new HashMap<>();
attributeValueMap.put(":lastNameValue", "John");
ScanSpec scanSpec = new ScanSpec().withFilterExpression("contains (lastName,:lastNameValue)")
.withValueMap(attributeValueMap);
IteratorSupport<Item, ScanOutcome> scanOutcome = null;
scanOutcome = table.scan(scanSpec).iterator();
while (scanOutcome.hasNext()) {
System.out.println("Output ==============>" + scanOutcome.next().toJSON());
}
Edit:-
As mentioned in other answers, you can use QuerySpec
if you know the hash key and lastname
is not defined as hash key. Also, you can use the contains
on FilterExpression
only. In other words, it can't be used on KeyConditionExpression
.
QuerySpec
needs KeyConditionExpression which will only support equality operator on hash key attribute. And then on FilterExpression
, you can use contains
on non-key attributes.
Upvotes: 0
Reputation: 2374
You cannot use contains
as part of a query, only a scan; but if you only care about results starting with a particular value, then you can use the begins_with
query operator: begins_with (a, substr)
(where a
is your key name). For this to work, the key must be a sort key, not a partition key. See http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/QueryAndScan.html#QueryAndScan.Query and http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/QueryingJavaDocumentAPI.html
Upvotes: 0
Reputation: 5195
Substring matching is something done well by ElasticSearch. I suggest you turn on your DynamoDB table's stream and index your items/documents in an AWS ElasticSearch cluster.
Upvotes: 1