使用DynamooseJs在DynamoDB中进行3列查询

时间:2018-10-07 18:47:09

标签: amazon-dynamodb dynamodb-queries dynamoose

我的表是(device, type, value, timestamp),其中(device,type,timestamp)构成唯一的组合(非DynamoDB DBMS中复合键的候选者)。

我的查询可以介于这三个属性之间,例如

从({{1})中获得(value的(device)大于(<type的(timestamp

我正在使用dynamoosejs/dynamoose。从大多数搜索中,我相信我应该将三个字段(作为单个字段; some-timestamp)的组合用作device-type-timestamp。但是,id的{​​{1}}不允许我使用对象属性(例如set: function),由于某些原因,我不能在外部使用它。

我最近得到的(Schema

({this.device

以此类推。

但是,在使用查询时,由于id:uuidv4:hashKey, device:string:GlobalSecIndex, type:string:LocalSecIndex, timestamp:Date:LocalSecIndex,(id:uuidv4:rangeKey, device:string:hashKey, type:string:LocalSecIndex, timestamp:Date:LocalSecIndexdevice,type)一直不在场景中,因此很难获取特定id的结果。

这个问题。这样的桌子怎么办?

需要注意的是,该表旨在从IoT设备收集内容,这些内容平均每台设备每5分钟生成一次。

2 个答案:

答案 0 :(得分:3)

我很好奇您为什么选择DynamoDB来完成此任务。这样的高级查询似乎比基于NoSQL的数据库更适合基于SQL的数据库。由于SQL查询的高级性质,以我的经验,此任务在SQL数据库中要容易得多。因此,我鼓励您考虑一下DynamoDB是否真的适合您在此尝试做的事情。

如果确定是,则可能需要稍微重组数据。您可以做一些类似的事情,例如拥有一个device-type属性,它将设备和类型值组合在一起。然后将其设置为索引,并根据该索引进行查询并按时间戳排序,然后过滤出不大于所需值的结果。

您是正确的,目前,Dynamoose并未将整个对象传递到set函数中。我个人愿意对此进行探索。我是GitHub项目的成员,并且如果您想提交添加该功能的PR,我将非常乐意与您一起探索该选项并将其纳入代码库。

您可能要探索的另一件事是拥有DynamoDB流,该流将在device-type属性添加到DynamoDB表中时进行设置。这样会将逻辑从DynamoDB和您的应用程序中抽象出来。我不确定将其解耦到该级别是否有必要,但这可能是您要探索的东西。

最后,根据您的设置,您可以找出哪个项目更独特,devicetype,然后在该属性上设置索引。然后,仅基于此查询,并过滤掉不需要的其他属性的结果。我不确定这是否是您要寻找的东西,它当然可以工作,但是我不确定您的表中将有多少个项目,并且在一定程度上存在关于可伸缩性的问题。解决其中一些可伸缩性问题的一种方法可能是,如果您知道要查询的时间戳是恒定的或可以提前预测的,则设置项目的TTL

总体而言,有很多方法可以实现您想要的目标。如果没有更多关于多少项目,这些属性将要做什么的详细信息,所需的可伸缩性的数量,这些属性中的哪些将是最独特的等等,这是很难做到的。我强烈建议您考虑NoSQL是否真的是最好的选择。您正在寻找的查询似乎更像是SQL查询。并不是说在DynamoDB中是不可能的,但是这需要您对如何构造数据模型等进行一些思考。

答案 1 :(得分:0)

考虑到@ charlie-fish的意见,我决定跳入Dynamoose并改进代码以将模型传递给属性的set函数。但是,我发现model已被传递到属性的default参数。因此,我将Schema更改为以下内容:

  id:hashKey;default: function(model){ return model.device + "" + model.type; }
  timestamp:rangeKey

对于落在此答案上的任何人,请注意defaultset函数可以使用this访问属性选项和架构实例。但是,这些功能都应该是常规功能,而不是箭头功能。

在这里将其保留为答案,但是一段时间内我不会接受它作为我的问题的答案,因为我想等别人找到更好的方法。 我还想确保如果为id字段传递了一个值,则不应设置该值。为此,我可以使用set来忽略实际的传入值,到目前为止,我还不知道该值。