AWS DynamoDB查询和排序

时间:2018-08-17 15:41:54

标签: amazon-web-services nosql amazon-dynamodb

一个社交媒体应用,人们可以在其中发布帖子。帖子由作者,时间戳,主题和正文组成。 这些帖子存储在DynamoDB中,其中Author作为分区键,TimeStamp作为排序键。

如何查询今天的所有帖子?我希望返回的结果在TimeStamp上进行排序,因此无法选择扫描DynamoDB。

查询操作基于主键值查找项目。因此,我必须定义一个全局二级索引。但是我找不到合适的选项来检索今天的所有帖子。什么是这里的好选择?

2 个答案:

答案 0 :(得分:1)

您可以添加一个表示日期的属性(您的GSI主键),并将时间戳属性设为GSI排序键

示例:

|   AuthorId  | Timestamp(GSI SK) | DayAttribute (GSI PK) |
|:-----------:|------------------:|:---------------------:|
| authord_id  |    1534522921     |     2018-08-17        |    
| authord_id2 |    1534522922     |     2018-08-17        |    
| authord_id3 |    1534522923     |     2018-08-18        |    

查询GSI时,它将按时间排序。

编辑您的评论:

添加属性来满足查询需求不是一个好方法。在这种情况下,我的建议是分层使用排序键。

这意味着将您最相关的查询合并到一个GSI密钥中,并使用分层排序密钥。假设您只想查询以月,周,天,小时,分钟为单位的细分。

这就是桌子

|   AuthorId  |      Timestamp(GSI SK)      |   MonthAttr (GSI PK)  |
|:-----------:|----------------------------:|:---------------------:|
| authord_id  |    2018:08:17::10:03:25     |       2018-08         |    
| authord_id  |    2018:08:17::10:03:25     |       2018-08         |    
| authord_id  |    2018:08:18::10:03:25     |       2018-08         |    

在此表中,通过使用诸如begins_with之类的排序键条件,您可以查询本月,10到15天之间或10到12小时之间的特定日期等所有项目。

例如,在过去13天的查询中,SortKey条件为begins_with(2018:08:04:),过去一个小时的查询类似于begins_with(2018:08:17:10:)

此方法引入了热分区密钥问题。看一看Time Series Data模型,以了解有关此方法的更多信息以及如何处理该方法

答案 1 :(得分:0)

假设你有如下表格:

resources:
  Resources:
    BotChatHistory:
      Type: 'AWS::DynamoDB::Table'
      DeletionPolicy: Retain
      Properties:
        TableName: ${self:provider.environment.DYNAMODB_BOT_CHAT_HISTORY_TABLE_NAME}
        AttributeDefinitions:
          - AttributeName: messageId
            AttributeType: S
          - AttributeName: userId
            AttributeType: S
          - AttributeName: createdDate
            AttributeType: S
        KeySchema:
          - AttributeName: messageId
            KeyType: HASH
        BillingMode: PAY_PER_REQUEST
        GlobalSecondaryIndexes:
        - IndexName: ${self:provider.environment.DYNAMODB_BOT_CHAT_HISTORY_TABLE_GSI_1}
          KeySchema:
          - AttributeName: userId
            KeyType: HASH
          - AttributeName: createdDate
            KeyType: RANGE
          Projection:
            ProjectionType: ALL 

然后你可以查询如下:

/**
 * 
 * getChatHistory
 * 
 */
const getChatHistory = async (organizationId, userId) => {
  return db('query', organizationId, {
    TableName: process.env.DYNAMODB_BOT_CHAT_HISTORY_TABLE_NAME,
    IndexName: process.env.DYNAMODB_BOT_CHAT_HISTORY_TABLE_GSI_1,
    KeyConditionExpression: "userId = :userId",
    ExpressionAttributeValues: {
        ":userId": userId
    },
    ScanIndexForward: true,
  });
}