我目前有一个用Perl编写的网站,使用Mojolicious和Mojo::Pg。它所做的一件事就是从我的Ninja Block温度传感器中取出并显示数据。我在Postgres中有四个表,outdoor_temperature
,outdoor_humidity
,而且在室内也是如此。表格如下所示:
Column | Type | Modifiers
--------+---------+-----------
time | bigint | not null
value | numeric | not null
date | date | not null
其中time
是一个以毫秒为单位的纪元值(每分钟一条记录),value
是温度或湿度,而date
就是那个(因此给定日期的每条记录都是如此)在date
列中具有相同的值。
我正在使用Node和Sails.js重写网站,主要是为了学习机会,而且我有点坚持在这里做事的最佳方式。在它的Perl化身中,我为每个Ninja Block相关函数设置了一个子程序(显示当前的当前温度,显示给定日期的最高/最低等),然后我通过它的位置。 (室内或室外),一切都从那里开始,像这样:
sub current {
my ( $self, $table ) = @_;
return $self->pg->db->query( "select time, value from $table where time = (select max(time) from $table)" )->hash;
}
但是使用Sails / Waterline,似乎模型只包含一个表。我的Perl版本中的任何表之间都没有连接,只能在每个表上使用.query
在Sails中完成一些半复杂的SQL查询,但我不确定如何在Sails下保留相同的设置,而无需在检查室内和室外表时复制一堆代码。
或者我是否完全错误地考虑了这一点,并且有更好的方法来实现这一切?
答案 0 :(得分:0)
我最终选择了位于控制器和模型之间的服务。控制器功能如下所示(使用与上面相同的示例):
currentTemperature: function(req, res) {
ninjaBlockService.getCurrentTemperature(req.param('location'), function(data) {
return res.json(data);
});
}
和服务功能:
getCurrentTemperature: function(location, callback) {
var query = "select time, value from " + location + "_temperature where time = (select max(time) from " + location + "_temperature)";
var locations = {
outdoor: function() {
NinjaBlockOutdoorTemperature.query(query, function(err, results) {
return callback(results.rows);
});
},
indoor: function() {
NinjaBlockIndoorTemperature.query(query, function(err, results) {
return callback(results.rows);
});
}
};
locations[location]();
}
它可能会更优雅,但它对我来说很有效。
因此,如果你使用的是Waterline的PostgreSQL本地.query
,你甚至不需要为多个表使用多个模型。我添加了一个名为NinjaBlock
的新模型,该模型没有任何属性或任何内容,并且可以运行我的查询,无论它们位于哪个表中。所以上面的函数现在看起来像这样:
getCurrentTemperature: function(location, callback) {
var query = "select time, value from " + location + "_temperature where time = (select max(time) from " + location + "_temperature)";
NinjaBlock.query(query, function(err, results) {
return callback(results.rows);
});
}
简单!