我正在为 DynamoDB 编写一个使用 aws-sdk 的 nodejs 5.7.1 应用程序。
我有一个使用以下代码创建的事件表:
var statsTableName='bingodrive_statistics';
var eventNameColumn = 'event_name';
var eventTimeColumn = 'event_time';
var eventDataColumn = 'event_data';
var params = {
TableName: statsTableName,
KeySchema: [ // The type of of schema. Must start with a HASH type, with an optional second RANGE.
{ // Required HASH type attribute
AttributeName: eventNameColumn,
KeyType: 'HASH',
},
{ // Optional RANGE key type for HASH + RANGE tables
AttributeName: eventTimeColumn,
KeyType: 'RANGE',
}
],
AttributeDefinitions: [ // The names and types of all primary and index key attributes only
{
AttributeName: eventNameColumn,
AttributeType: 'S', // (S | N | B) for string, number, binary
},
{
AttributeName: eventTimeColumn,
AttributeType: 'N'
}
],
ProvisionedThroughput: { // required provisioned throughput for the table
ReadCapacityUnits: 1,
WriteCapacityUnits: 1,
}
};
dynamodbClient.createTable(params, callback);
如您所见,我有一个哈希 + 范围索引。 范围在event_time。
现在我想扫描或查询两个特定日期之间的所有项目。
所以我将以下参数发送到 dynamoDB 的查询函数:
{
"TableName": "bingodrive_statistics",
"KeyConditionExpression": "event_time BETWEEN :from_time and :to_time",
"ExpressionAttributeValues": {
":from_time": 1457275538691,
":to_time": 1457279138691
}
我收到此错误:
{
"message": "Query condition missed key schema element",
"code": "ValidationException",
"time": "2016-03-06T15:46:06.862Z",
"requestId": "5a672003-850c-47c7-b9df-7cd57e7bc7fc",
"statusCode": 400,
"retryable": false,
"retryDelay": 0
}
我是dynamoDb的新手。我不知道最好的方法是什么,在我的情况下是扫描或查询。 有关该问题的任何信息将不胜感激。
你应该使用 query
.如果要查询两个范围键之间的值,则不能仅使用范围键,还需要使用哈希键以及范围键。这是因为哈希键(分区键)用于选择存储数据的物理分区,按范围键(排序键)排序。来自 DynamoDB 开发人员指南:
如果表具有复合主键(分区键和排序键),DynamoDB 将按照数据分布:分区键中所述的方式计算分区键的哈希值,但它存储具有相同分区键值的所有项目在物理上靠近在一起,按排序键值排序。
此外,您应该选择能够很好地分发数据的分区键。如果 evenName 的值总数较少,则可能不是最佳选择(请参阅表指南]
也就是说,如果您已经将eventName
作为哈希键,eventTime
作为范围键,则应查询(抱歉伪代码,我通常使用 DynamoDBMapper):
hashKey = name_of_your_event
conditions = BETWEEN
attribute_values (eventTime1, eventTime2)
为此,您不需要额外的本地二级索引或全局二级索引。请注意,GSI 允许您查询未使用表哈希和范围键编制索引的列,但要查询时间戳之间的数据,您仍然需要一个范围键,否则需要执行扫描。
使用此查询
function getConversationByDate(req , cb) {
var payload = req.all; //05/09/2017
var params = {
TableName: "message",
IndexName: "thread_id-timestamp-index",
KeyConditionExpression: "#mid = :mid AND #time BETWEEN :sdate AND :edate",
ExpressionAttributeNames: {
"#mid": "thread_id",
"#time": "timestamp"
},
ExpressionAttributeValues: {
":mid": payload.thread_id,
":sdate": payload.startdate,
":edate": payload.enddate
}
};
req.dynamo.query(params, function (err, data) {
cb(err, data);
});
}