我可以成功从 Redis 收集指标,但我还想通过设备 ID 收集它。最简单的方法是什么?
在这里,我使用下划线和 bluebird。
所需对象:
[
{
deviceId : 'foo',
stats: [
{
date : '20160215',
temperature : 32.3,
uptime : 10.0,
frequency : 0.2
},
{
date : '20160216',
temperature : 12.3,
uptime : 15.0,
frequency : 0.3
}
// ,...
]
},
{
deviceId : 'bar',
stats: [
{
date : '20160215',
temperature : 42.3,
uptime : 0.3,
frequency : 0.5
},
{
date : '20160216',
temperature : 32.3,
uptime : 1.2,
frequency : 0.5
}
// ,...
]
}
]
数据以有序集的形式存储在redis中:
// metric:device:device-id:daily
temperature:device:standart-faf4-4279-a040-0e729e53f5c1:daily
uptime:device:standart-faf4-4279-a040-0e729e53f5c1:daily
frequency:device:standart-faf4-4279-a040-0e729e53f5c1:daily
我的代码:
var metrics = [ 'temperature', 'uptime', 'frequency' ];
var signals = _
.chain(statsOfToday)
.pluck('deviceId')
.map(function(deviceId) {
return _.map(metrics, function(metric) {
return redis.zrangebyscoreAsync(
metric +":device:"+ deviceId +":daily",
20160215, 20160216
);
})
})
.flatten()
.value();
// in here deviceId is lost
return Promise.all(signals)
.then(function(results) {
return _
.chain(results)
.flatten()
.map(function(x) {
// data in redis stored as: metric-timestamp
return x.split("-")[0];
})
.value();
});
最佳答案
据我所知,您的第一个语句会产生一系列不包含它们引用的 deviceId 的值的 promise ,这使得第二步中处理它们变得更加困难。
那么这个怎么样:
var signals = _
.chain(statsOfToday)
.pluck('deviceId')
.map(function(deviceId) {
return _.map(metrics, function(metric) {
return redis.zrangebyscoreAsync(
metric +":device:"+ deviceId +":daily", 20160215, 20160216
).then(function (data) {
return data.map(function (item) {
return {
deviceId: deviceId,
metric: metric,
data: item.split("-")[0]
};
});
});
})
})
.flatten()
.value();
通过这种方式,您可以获得包含 deviceId
、metric
以及来自 Redis 的关联data
的值的 promise 数组。
在 Promise.all(signals)
中可以对数据进行分组/将其调整为形状。
更易于阅读且更易于重用:
function getDeviceMetricAsync(deviceId, metric, min, max) {
var key = metric + ":device:" + deviceId + ":daily";
return redis.zrangebyscoreAsync(key, min, max).map(function (item) {
return {
deviceId: deviceId,
metric: metric,
data: item.split("-")[0]
}
});
}
var signals = _
.chain(statsOfToday)
.pluck('deviceId')
.map(function(deviceId) {
var retrievalFunc = _.partial(getDeviceMetricAsync, deviceId, _, 20160215, 20160216);
return _.map(metrics, retrievalFunc);
})
.flatten()
.value();
注意: redis.zrangebyscoreAsync(key, min, max).map(...)
行假定 Redis API 使用 Bluebird Promise,即 var Promise = require('Bluebird');
应在导入 Redis 之前完成。
普通的 Promise API 不支持 .map()
,如果 Redis 有自己的 Promise 实现,您必须手动执行此操作。
关于javascript - 如何用下划线对一系列 promise 进行分组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35466655/