gpt4 book ai didi

java - DynamoDB - 查询而不是扫描 - 如何使用随机生成的 key 实现

转载 作者:行者123 更新时间:2023-12-02 11:46:08 27 4
gpt4 key购买 nike

设置

我在 java 和 DynamoDB (DynamoDB Mapper) 注释中有下表:

@DynamoDBTable(tableName="myentity")
public class MyEntity {
@DynamoDBHashKey
@DynamoDBAutoGeneratedKey
private String id;

@DynamoDBIndexHashKey()
//@DynamoDBIndexRangeKey
private String userId;

private Date eventDate;

保存时id是随机生成的,多个实体可以出现相同的userId

通过 Web GUI 定义的表如下所示:主分区键:id(字符串)主排序键:userId(字符串)

问题

我希望通过查询而不是扫描来获取一个用户 ID 的所有实体。

查询 - 不能像这样工作:

public List<MyEntity> findByUserIdQuery(String userId) {
Map<String, AttributeValue> eav = new HashMap<String, AttributeValue>();
eav.put(":val1", new AttributeValue().withS(userId));

DynamoDBQueryExpression<MyEntity> queryExpression = new DynamoDBQueryExpression<MyEntity>()
.withKeyConditionExpression("userId = :val1").withExpressionAttributeValues(eav);

List<MyEntity> list = mapper.query(MyEntity.class, queryExpression);

我当然明白:

com.amazonaws.AmazonServiceException: Query condition missed key schema element: id (Service: AmazonDynamoDBv2; Status Code: 400; Error Code: ValidationException; Request ID: 123) at com.amazonaws.http.AmazonHttpClient.handleErrorResponse(AmazonHttpClient.java:1305)

因为我想读取数据时不知道生成的id。

解决方法

我使用:

public List<MyEntity> findByOwner(String userId){

Map<String, AttributeValue> eav = new HashMap<String, AttributeValue>();
eav.put(":val1", new AttributeValue().withS(userId));

DynamoDBScanExpression scanExpression = new DynamoDBScanExpression()
.withFilterExpression("userId = :val1").withExpressionAttributeValues(eav);

List<MyEntity> list = mapper.scan(MyEntity.class, scanExpression);

可能的解决方案

问题是我永远不知道我所拥有的元素的随机生成的 key 。当我想阅读时,我只知道 userId,并且我想拥有它们的所有实体。

我在这里观看了示例: https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/DynamoDBMapper.QueryScanExample.html...但他们始终知道他们正在寻找的东西的关键。他们使用这样的组合键:

String partitionKey = forumName + "#" + threadSubject;*
eav.put(":val1", new AttributeValue().withS(partitionKey))
Map<String, AttributeValue> eav = new HashMap<String, AttributeValue>();
DynamoDBQueryExpression<Reply> queryExpression = new DynamoDBQueryExpression<Reply>()
.withKeyConditionExpression("Id = :val1 and ReplyDateTime > :val2").withExpressionAttributeValues(eav);

问题

  • 我可以使用这个组合分区键的通配符之类的东西吗? (类似于:“* # myGreatUser”)
  • 关于数据库设置和其他注释作为关键元素的其他建议?
  • 也许是一个我可以使用查询而不是扫描的索引?
  • 也许有人有此类用例的有效示例?

最佳答案

您只需切换分区键和排序键即可。

@DynamoDBTable(tableName="myentity")
public class MyEntity {

@DynamoDBRangeKey
@DynamoDBAutoGeneratedKey
private String id;

@DynamoDBHashKey
private String userId;

private Date eventDate;

然后使用查询

public List<MyEntity> findByUserIdQuery(String userId) {
Map<String, AttributeValue> eav = new HashMap<String, AttributeValue>();
eav.put(":val1", new AttributeValue().withS(userId));

DynamoDBQueryExpression<MyEntity> queryExpression = new DynamoDBQueryExpression<MyEntity>()
.withKeyConditionExpression("userId = :val1").withExpressionAttributeValues(eav);

List<MyEntity> list = mapper.query(MyEntity.class, queryExpression);

顺便说一句,您提到您认为排序键是 userId,但在提供的示例中,您有一个主哈希键 id 和一个全局辅助索引哈希键 userid。没有排序键。

关于java - DynamoDB - 查询而不是扫描 - 如何使用随机生成的 key 实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48191746/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com