扫描两个时间戳之间的查询

我正在为DynamoDB使用aws-sdk编写nodejs 5.7.1应用程序。

我有一个我用下面的代码创build的事件表:

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); 

正如你所看到的,我有一个Hash + Range索引。 范围在event_time。

现在我想扫描或查询两个特定date之间的所有项目。

所以我发送以下的参数dynamoDb的查询function:

 { "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 。 如果要查询两个范围键之间的值,则不能使用范围键,因此您还需要使用散列键以及范围键。 这是因为散列键(分区键)用于select存储数据的物理分区,按范围键(sorting键)sorting。 从DynamoDB开发者指南 :

如果表具有组合主键(分区键和sorting键),则DynamoDB将按照“数据分配:分区键”中所述的相同方式计算分区键的哈希值,但它将使用相同的分区键存储所有项值物理上靠近在一起,按sorting键值sorting。

另外,你应该select分配你的数据的分区键。 如果偶数名称的值总数很less,则可能不是最好的select(请参阅表格准则 )

也就是说,如果你已经有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); }); }