本文详解如何利用 dynamodb 全局二级索引(gsi)结合时间戳字段,高效查询过去 15 分钟内写入的数据,涵盖 java sdk 实现、时间计算逻辑、关键注意事项及完整代码示例。
在 DynamoDB 中实现“获取最近 15 分钟数据”这一常见需求,不能像传统 SQL 那样使用 WHERE create_time > NOW() - INTERVAL 15 MINUTE,而需依托其基于主键的查询机制——尤其是当您已创建以 materialType 为分区键(Hash Key)、createTime 为排序键(Sort Key)的全局二级索引(GSI)时,可通过 Query 操作 + 时间范围条件表达式 精准、高效地完成。
DynamoDB 的 createTime 存储为毫秒级时间戳(Instant.now().toEpochMilli()),因此需在客户端计算 15 分钟前的时间点:
long fifteenMinutesAgo = Instant.now().minus(15, ChronoUnit.MINUTES).toEpochMilli();
⚠️ 注意:务必使用 Instant(而非 System.currentTimeMillis())以确保时区无关性和精度一致性;若业务跨多时区,建议统一使用 UTC 存储与计算。
import software.amazon.awssdk.auth.credentials.DefaultCredentialsProvider;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
import software.amazon.awssdk.services.dynamodb.model.*;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
public class DynamoDBRecentItemsQuery {
public static void main(String[] args) {
DynamoDbClient dynamoDb = DynamoDbClient.builder()
.region(Region.US_EAST_1)
.credentialsProvider(DefaultCredentialsProvider.create())
.build();
String tableName = "mytable";
String indexName = "myindex"; // 您创建的 GSI 名称
String materialType = "ITEM_TYPE_A";
// 计算 15 分钟前的时间戳(毫秒)
long fifteenMinutesAgo = Instant.now()
.minus(15, ChronoUnit.MINUTES)
.toEpochMilli();
// 构建 Query 请求
QueryRequest queryRequest = QueryRequest.builder()
.tableName(tableName)
.indexName(indexName)
.keyConditionExpression("materialType = :v1 AND createTime > :v2")
.expressionAttributeValues(Map.of(
":v1", AttributeValue.builder().s(materialType).build(),
":v2", AttributeValue.builder().n(String.valueOf(fifteenMinutesAgo)).build()
))
.build();
try {
QueryResponse response = dynamoDb.query(queryRequest);
response.items().forEach(item ->
System.out.println("Found item: " + item));
} catch (DynamoDbException e) {
System.err.println("Query failed: " + e.getMessage());
}
}
}DynamoDB 的时间范围查询本质是「分区键精确匹配 + 排序键范围扫描」。只要合理设计 GSI(materialType 作 Hash Key,createTime 作 Sort Key),并正确构造 keyConditionExpression 与动态时间戳参数,即可在毫秒级响应内获取最近 15 分钟的全部数据——既符合 NoSQL 最佳实践,又兼顾性能、成本与可维护性。