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

DynamoDB 对二级索引的查询,如何定义索引

乐宜民
2023-03-14

我一直在绕来绕去,只是不清楚该怎么做。

我有一个简单的表,我想在其中对几列进行查询。据我了解,这意味着为要查询的每一列创建一个二级索引。我已经定义了表 - 使用无服务器框架serverless.yml - 并且收到各种奇怪的错误消息。

当前的服务器 .yml 定义为:

resources:
  Resources:
    MessagesDynamoDBTable:
      Type: 'AWS::DynamoDB::Table'
      Properties:
        AttributeDefinitions:
          - AttributeName: messageId
            AttributeType: S
          - AttributeName: room
            AttributeType: S
          - AttributeName: userId
            AttributeType: S
        KeySchema:
          - AttributeName: messageId
            KeyType: HASH
          - AttributeName: userId
            KeyType: RANGE
        LocalSecondaryIndexes:
          - IndexName: roomIndex
            KeySchema: 
              - AttributeName: room
                KeyType: HASH
            Projection: 
              ProjectionType: "KEYS_ONLY"
          - IndexName: userId
            KeySchema: 
              - AttributeName: userId
                KeyType: HASH
            Projection: 
              ProjectionType: "KEYS_ONLY"
        ProvisionedThroughput:
          ReadCapacityUnits: 1
          WriteCapacityUnits: 1
        TableName: ${self:custom.tableName}

它的意思类似于 Slack 服务 - 因此我想查询来自房间、用户等的条目。

根据我能够找到的文档,这个定义是有意义的。一个应该为索引中使用的列声明属性,我已经这样做了。键模式 - 我真的只需要 messageId 字段,但一条错误消息指示它需要一个范围索引,所以我将 userId 字段添加到键模式中只是为了关闭它。根据我能够找到的文档,二级索引字段看起来是正确的。

使用此定义,我在尝试使用无服务器部署进行部署时收到此错误

An error occurred: MessagesDynamoDBTable - Property AttributeDefinitions is inconsistent 
with the KeySchema of the table and the secondary indexes.

我尝试了几种变体,但也遇到了其他奇怪的错误。以下是一些,但我不记得对定义的相应更改是什么。

An error occurred: MessagesDynamoDBTable - One or more parameter values were invalid: 
Index KeySchema does not have a range key for index: userId (Service: AmazonDynamoDBv2; Status Code: 400;
Error Code: ValidationException; Request ID: 1KFA2IMASC12HRLLDPG753CU63VV4KQNSO5AEMVJF66Q9ASUAAJG).

An error occurred: MessagesDynamoDBTable - 1 validation error detected: Value '[com.amazonaws.dynamodb.v20120810.KeySchemaElement@aa4cdc91, 
com.amazonaws.dynamodb.v20120810.KeySchemaElement@d2cd6f64, com.amazonaws.dynamodb.v20120810.KeySchemaElement@4d7c1f9, 
com.amazonaws.dynamodb.v20120810.KeySchemaElement@d2cd6f64]' at 'keySchema' failed to satisfy constraint: Member must have length less
 than or equal to 2 (Service: AmazonDynamoDBv2; Status Code: 400; Error Code: ValidationException; Request ID: BOVVBQ1F35VA18CCF3L5MSKS1FVV4KQNSO5AEMVJF66Q9ASUAAJG).

An error occurred: MessagesDynamoDBTable - Property AttributeDefinitions is inconsistent with the KeySchema 
of the table and the secondary indexes.

An error occurred: MessagesDynamoDBTable - One or more parameter values were invalid: Index KeySchema does not have a range key for index:
 userIdIndex (Service: AmazonDynamoDBv2; Status Code: 400; Error Code: ValidationException; Request ID: KFS63VSPKDUC60DV6U2V47UP27VV4KQNSO5AEMVJF66Q9ASUAAJG).

An error occurred: MessagesDynamoDBTable - One or more parameter values were invalid: Table KeySchema does not have a range key,
 which is required when specifying a LocalSecondaryIndex (Service: AmazonDynamoDBv2; Status Code: 400; Error Code: ValidationException; Request ID: 86Q2JSPM6Q9UPNIEOVHALLIIQJVV4KQNSO5AEMVJF66Q9ASUAAJG).

共有1个答案

朱刚捷
2023-03-14

它不起作用的原因是本地二级索引中的键必须与表具有相同的分区键。因此,在您的情况下,您的本地二级索引必须将 messageId 作为其哈希键,房间用户 ID 作为其各自索引上的范围键。由于您的表已经由(messageId,userId)键控,因此您不需要userId本地二级索引。

从技术上讲,此设置将起作用:

MessagesDynamoDBTable:
  Type: AWS::DynamoDB::Table
  Properties:
    AttributeDefinitions:
      - AttributeName: messageId
        AttributeType: S
      - AttributeName: room
        AttributeType: S
      - AttributeName: userId
        AttributeType: S
    KeySchema:
      - AttributeName: messageId
        KeyType: HASH
      - AttributeName: userId
        KeyType: RANGE
    LocalSecondaryIndexes:
      - IndexName: roomIndex
        KeySchema:
          - AttributeName: messageId
            KeyType: HASH
          - AttributeName: room
            KeyType: RANGE
        Projection:
          ProjectionType: KEYS_ONLY
    ProvisionedThroughput:
      ReadCapacityUnits: 1
      WriteCapacityUnits: 1
    TableName: ${self:custom.tableName}

但是,如果要按会议室和用户进行查询,则可能需要使用不同的表设计。您尝试执行的操作最终会要求您始终使用 messageId 作为查询的一部分来查询表,因为它是分区键。因此,您将无法仅通过房间用户 ID 进行查询。您可能想要的是全局二级索引。在这种情况下,这将起作用:

MessagesDynamoDBTable:
  Type: AWS::DynamoDB::Table
  Properties:
    AttributeDefinitions:
      - AttributeName: messageId
        AttributeType: S
      - AttributeName: room
        AttributeType: S
      - AttributeName: userId
        AttributeType: S
    KeySchema:
      - AttributeName: messageId
        KeyType: HASH
    GlobalSecondaryIndexes:
      - IndexName: roomIndex
        KeySchema:
          - AttributeName: room
            KeyType: HASH
        Projection:
          ProjectionType: KEYS_ONLY
        ProvisionedThroughput:
          ReadCapacityUnits: 1
          WriteCapacityUnits: 1
      - IndexName: userIndex
        KeySchema:
          - AttributeName: userId
            KeyType: HASH
        Projection:
          ProjectionType: KEYS_ONLY
        ProvisionedThroughput:
          ReadCapacityUnits: 1
          WriteCapacityUnits: 1
    ProvisionedThroughput:
      ReadCapacityUnits: 1
      WriteCapacityUnits: 1
    TableName: ${self:custom.tableName}

请注意,制作 ProjectionType: KEYS_ONLY 意味着当您查询 roomIndex 或 userIndex,您得到的只是 messageIds - 然后您必须使用 messageId 重新查询表以获取其他属性。您可能希望使用不同的投影类型,具体取决于您的使用模式。

 类似资料:
  • 我希望使用DynamoDB表来请求我在查询中创建的二级索引。 从现在开始,对于我正在做的一个二级索引: 我会像这样构建我的KeyConditionExpression: 我读了一遍又一遍这份文件,但我不知道怎么做: https://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/gettingstartedguide/GettingStarted.P

  • 我的主键是一个名为“ID”的字段 我在表中的字段“group_number”上添加了一个辅助索引 我通过二级索引进行查询,如下所示: 然而;我得到错误“ValidationException:query condition missed key schema Element:ID” DynamoDB只允许查询主键吗?我的印象是您使用“getitem”作为主键,因为如果您使用一个主键,只有一个记录可

  • 是否有一种方法可以使用查询dynamodb的。我找不到任何在线教程或资源。

  • 我正在DynamoDB中创建一个表和GSI,使用以下参数,如文档所示: 是表的主键,我使用作为GSI的主键。(为了简洁起见,我删除了一些不必要的配置参数) 我正在使用以下命令查询此表: 但我一直在犯错误: "一个或多个参数值无效:条件参数类型与模式类型不匹配" 在文档中,它指定主可以是或,并且您可以在字段中设置。我正在以的形式发送,不确定这里缺少了什么。 问题是在我创建表的方式上,还是在我查询表的

  • 我有以下带有三个全局二级索引(GSI)的DyamoDB表 Id(主键)、user_id(GSI)、event_type(GSI)、product_id(GSI)、rate、create_date 我有以下三种查询模式: null null

  • 本文(https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/bp-indexes-gsi-sharding.html)讨论一种通过引入一个随机整数作为分区键,在多个分区之间对全局二级索引值进行分片的技术。 这对我来说是有意义的,但本文没有清楚地解释如何查询该索引。假设我使用一个1-10的随机整数作为分区键,一个数字作为排序

  • 问题: 主键为复合哈希范围键的DynamoDB表是唯一的。这是否也延伸到二级指数? 示例: 我有一个带有post_id主键和comment_id范围键的comments DynamoDB表。此外,还有一个带有date-user_id范围键的本地辅助索引。 每个条目都是用户在发布时留下的评论。二级索引的目的是统计在特定的一天,有多少唯一的用户在一个帖子上留下了评论。 条目1:post_id:1 co

  • 我有一个DynamoDB表,分区键为userID,没有排序键。该表在每个项目中还具有时间戳属性。我想检索在指定范围内具有时间戳的所有项目(无论用户ID如何,即跨所有分区)。在阅读文档并搜索堆栈溢出(此处)后,我发现需要为我的表创建一个GSI。因此,我使用以下键创建了一个GSI: 分区键: 排序键: 我正在使用Java SDK使用以下代码查询索引: 执行此代码时出现以下错误: 据我所知,我应该能够仅