我的表是(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:LocalSecIndex
或device,type
)一直不在场景中,因此很难获取特定id
的结果。
这个问题。这样的桌子怎么办?
需要注意的是,该表旨在从IoT设备收集内容,这些内容平均每台设备每5分钟生成一次。
答案 0 :(得分:3)
我很好奇您为什么选择DynamoDB来完成此任务。这样的高级查询似乎比基于NoSQL的数据库更适合基于SQL的数据库。由于SQL查询的高级性质,以我的经验,此任务在SQL数据库中要容易得多。因此,我鼓励您考虑一下DynamoDB是否真的适合您在此尝试做的事情。
如果确定是,则可能需要稍微重组数据。您可以做一些类似的事情,例如拥有一个device-type
属性,它将设备和类型值组合在一起。然后将其设置为索引,并根据该索引进行查询并按时间戳排序,然后过滤出不大于所需值的结果。
您是正确的,目前,Dynamoose并未将整个对象传递到set
函数中。我个人愿意对此进行探索。我是GitHub项目的成员,并且如果您想提交添加该功能的PR,我将非常乐意与您一起探索该选项并将其纳入代码库。
您可能要探索的另一件事是拥有DynamoDB流,该流将在device-type
属性添加到DynamoDB表中时进行设置。这样会将逻辑从DynamoDB和您的应用程序中抽象出来。我不确定将其解耦到该级别是否有必要,但这可能是您要探索的东西。
最后,根据您的设置,您可以找出哪个项目更独特,device
或type
,然后在该属性上设置索引。然后,仅基于此查询,并过滤掉不需要的其他属性的结果。我不确定这是否是您要寻找的东西,它当然可以工作,但是我不确定您的表中将有多少个项目,并且在一定程度上存在关于可伸缩性的问题。解决其中一些可伸缩性问题的一种方法可能是,如果您知道要查询的时间戳是恒定的或可以提前预测的,则设置项目的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
对于落在此答案上的任何人,请注意default
和set
函数可以使用this
访问属性选项和架构实例。但是,这些功能都应该是常规功能,而不是箭头功能。
在这里将其保留为答案,但是一段时间内我不会接受它作为我的问题的答案,因为我想等别人找到更好的方法。
我还想确保如果为id
字段传递了一个值,则不应设置该值。为此,我可以使用set
来忽略实际的传入值,到目前为止,我还不知道该值。