一个社交媒体应用,人们可以在其中发布帖子。帖子由作者,时间戳,主题和正文组成。 这些帖子存储在DynamoDB中,其中Author作为分区键,TimeStamp作为排序键。
如何查询今天的所有帖子?我希望返回的结果在TimeStamp上进行排序,因此无法选择扫描DynamoDB。
查询操作基于主键值查找项目。因此,我必须定义一个全局二级索引。但是我找不到合适的选项来检索今天的所有帖子。什么是这里的好选择?
答案 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,
});
}