当前位置: 首页 > 知识库问答 >
问题:

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

禄烨然
2023-03-14

安装程序

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

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

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

private Date eventDate;

保存时会随机生成id,多个实体可能会出现相同的用户id。

通过Web GUI定义的表如下:主分区键:id(String)主排序键:userId(String)

问题

我想用一个查询而不是扫描获得一个用户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);

可能的解决方案

问题是我从来都不知道随机生成的元素键。当我想阅读时,我只知道用户ID,我想拥有他们的所有实体。

我观看了以下示例: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")
  • 关于db设置和其他注释作为关键元素的其他建议?
  • 也许是一个可以使用查询而不是扫描的索引?
  • 也许有人有这种用例的工作示例?

共有1个答案

乜烨霖
2023-03-14

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

@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的全局二级索引哈希键。没有排序键。

 类似资料:
  • DynamoDb文档中指定的查询操作: 查询操作仅搜索主键属性值,并支持对键属性值的比较运算符子集以优化搜索过程。 和扫描操作: 扫描操作扫描整个表。您可以指定要应用于结果的过滤器,以在完成扫描后优化返回给您的值。 这是基于性能和成本考虑的最佳选择。

  • 问题内容: 我目前正在使用Spring 3.1和Hibernate 4通过以下方式扫描DAO和服务的软件包:是否可以对标记的类执行相同的操作,而不是使用属性和文件? 问题答案: 将扫描模型包中的所有内容。我使用cfg.xml包含show_sql和hb2ddl.auto之类的设置。

  • 问题内容: 我试图扫描JedisCluster中存储的特定密钥。 在这里,我得到了空值。但是群集节点中存储了一个值。 但是,如果我尝试扫描每个Jedis池,我将得到结果。 为什么JedisCluster扫描方法无法提供正确的结果?我该如何解决这个问题? 注意:我可以用来检查密钥的存在。但是我需要使用扫描,因为我可以对Jedis和JedisCluster使用相同的界面。 问题答案: 第1部分: 在您

  • 我的DynamoDB表数据架构: 我的主要用例是,我有一个“PK”和“SK”的范围,这是目标时间范围,并查询DDB以获得“摘要”列表。这种数据设计适用于DDB API。 现在,我想使用AppSync为这个DynamoDB for Amplify应用程序创建一个GraphQL API。所以我创建了一个像这样的GraphQL模式: GraphQL自动为我创建了2个查询API:和。支持我的是,当我列出A

  • 问题内容: 我正在尝试在Java中生成盐,以与用于安全密码存储的哈希算法配合使用。我正在使用以下代码创建随机盐: 这应该生成一个完全安全的,随机生成的盐,以用于我的哈希算法。但是,当我运行代码时,每次都会输出相同的盐…表示生成的盐根本不是随机的。 出于明显的安全性目的,每个用户都需要一个唯一的符号,但是如果我每次创建一个新帐户时都使用此代码,则每个用户都将具有相同的符号,这一开始就破坏了它的用途。

  • 我正在尝试查询我的dynamodb表以获取提要\u guid和状态\u id=1。但它返回查询键条件不受支持的错误。请查找我的表架构和查询。 以下是我更新该表的查询。