DynamoDB:构建和查询带时间戳的日志的排序列表的最佳方法是什么?

时间:2016-01-09 18:25:11

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

为了更好地理解亚马逊的DynamoDB,Lambda函数和IAM角色(我将在这个问题中坚持使用DynamoDB),我正在设置一个Linux设备来监听新的DynamoDB项目并以可听见的方式读出更新由其他功能定期添加。我的目标是查询或扫描项目,从特定时间戳(设备最后一次检查)开始按升序返回这些项目。

这是我到目前为止使用的项目结构:

{
  "datetime": { //sort key
    "S": "2016-01-11T05:15:02"
  },
  "message": {
    "S": "It is all good."
  },
  "reporter": { //primary partition key
    "S": "SF Reporter"
  },
  "status": {
    "S": "ok"
  }
}

“id”是分区键。 “时间”是排序键。现在看着这个,我猜我应该把“时间”变成一个数字,而不是一个字符串......

查询或扫描?查询似乎是排序的正确选项,但它需要查询中的特定分区ID(至少在AWS网站查询工具中),所以也许我正在添加错误。扫描加载所有项目,我猜测排序不是自动的或选项(至少不在AWS网站查询工具中)。我真的只想加载大于时间戳值的项目,已排序。

我的思绪在哪里?我提前感谢您的帮助。

更新

在进一步使用AWS-CLI和DynamoDB进行实验后,我最终使用了略有不同的解决方案。由于这是一个小规模的“hello world”类型的项目,所以所有更新项目都将使用单个分区键“SF Reporter”添加到同一个表中。如果我决定开始使用单独的查询和/或设备监视其他“报告者”/服务更新,则可能会扩展。

var AWS = require("aws-sdk");
AWS.config.credentials = new AWS.SharedIniFileCredentials({ profile: 'default' });
AWS.config.update({"region": "us-west-2"});
var docClient = new AWS.DynamoDB.DocumentClient();

var params = {
    TableName: "spoken_reports",
    KeyConditionExpression: "#reporter = :reporter and #datetime >= :datetime",
    ExpressionAttributeNames:{
        "#reporter": "reporter",
        "#datetime": "datetime"
    },
    ExpressionAttributeValues: {
        ":reporter":"SF Reporter",
        ":datetime":"2016-01-11T05:15:02"
    }
};

docClient.query(params, onUpdatesReceived);

var onUpdatesReceived = function(err, data) { 
    if (err) {
        console.log(err, err.stack);
    } else {
        console.log(data);
    }
}

JSON查询本身看起来像这样(缩写为node.js示例):

{{1}}

查询获取按字符串时间戳排序的最新更新(在此示例中默认为升序)。这允许进行一些扩展,因为我可以让多个设备检查同一个表以获取最新更新。我会创建一个预定的查询/功能,以便偶尔清除旧的更新,以保持清晰。

2 个答案:

答案 0 :(得分:0)

如果您坚持使用此表设计,扫描整个表是您唯一的选择,因为您提到的原因:对于查询,您需要一个分区键,这是您的设备无法使用的事先知道。

我想到了另一种解决方案:

  • 让我们说你当前的表叫做T1。创建另一个表T2,其中deviceID为分区键,timestamp为排序键。
  • 您可以在T1的流上定义AWS Lambda函数,在任何更新时,它也会在T2中推送该行,每个设备一个。
  • 现在,只要您的设备被唤醒,它就会使用自己的设备ID查询(不扫描)T2。处理所有行并删除它们。

换句话说,T2将始终拥有给定设备尚未处理的所有行。

答案 1 :(得分:0)

死的简单方法:

您应该设置一个全局二级索引,并将“isNew”项目作为其主键/哈希键,并将时间戳作为范围键。

创建条目时,将<div class="main-image content-fill" style="display:none">. 标记为UUID或其他内容。这将使表项目项目成为索引。

当您需要检查数据时,isNew二级索引 - 索引将只有新的结果。然后,scan您在表格中读取的项目,以删除项目上的updateItem键。该项目将从二级索引中删除,因此不会再次读取。