我有一个名为Users的DynamoDb表。我正在尝试执行一个非常简单的查询,其中用户的姓氏类似于John *' (约翰逊,约翰斯顿,约翰尼等),但我找不到一个非常直截了当的例子。
以下是我的代码片段:
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");
...
}
}
有人可以指出我正确的方向吗?我试着查看Query
对象,但我不确定它会做我需要的对象。
我不得不使用
Scan
对象来完成这项工作,但它会对每个查询进行全表扫描。
有没有人找到更好/更快的部分值搜索方式?
以下会更快吗?
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");
...
}
}
答案 0 :(得分:1)
子弹串匹配是ElasticSearch完成的。我建议您打开DynamoDB表的流并在AWS ElasticSearch集群中索引您的项目/文档。
答案 1 :(得分:0)
以下ScanSpec
使用contains
部分匹配字符串。
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());
}
修改: - 强>
如其他答案中所述,如果您知道散列键并且QuerySpec
未定义为散列键,则可以使用lastname
。此外,您只能使用contains
上的FilterExpression
。换句话说,它无法在KeyConditionExpression
上使用。
QuerySpec
需要KeyConditionExpression,它只支持散列键属性上的相等运算符。然后在FilterExpression
上,您可以对非关键属性使用contains
。
答案 2 :(得分:0)
您不能将disable=C0326
用作查询的一部分,只能用于扫描;但是如果您只关心具有特定值的开始的结果,那么您可以使用contains
查询运算符:begins_with
(其中begins_with (a, substr)
是您的密钥名称) 。为此,键必须是排序键,而不是分区键。请参阅http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/QueryAndScan.html#QueryAndScan.Query和http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/QueryingJavaDocumentAPI.html