我有一组文件,其中包含服务器名称,以及该服务器的开始时间戳和结束时间戳。例如
[
{
serverName: "Houston",
startTimestamp: "2018/03/07 17:52:13 +000",
endTimestamp: "2018/03/07 18:50:10 +000"
},
{
serverName: "Canberra",
startTimestamp: "2018/03/07 18:48:09 +000",
endTimestamp: "2018/03/07 20:10:00 +000"
},
{
serverName: "Melbourne",
startTimestamp: "2018/03/08 01:43:13 +000",
endTimestamp: "2018/03/08 12:09:10 +000"
}
]
有了这些数据,给定一个时间戳我需要在那个时间点获取活动服务器列表。
例如。对于来自上述数据的TS="2018/03/07 18:50:00 +000"
,活动服务器列表为["Huston", "Canberra"]
是否可以使用仅CouchDB视图来实现此目的。如果是这样怎么办呢?
注意:最初我尝试了以下方法。在map函数中我发出两个文档
key=doc.startTimestsamp
和value={"station_add": doc.station}
key=doc.startEndtsamp
和value={"station_rem": doc.station}
我的目的是在"station_add"
中添加减少功能并删除"stations_rem"
中的工作站来迭代这些功能。但是我发现 CouchDB没有提到有关reduce函数中值的排序的任何内容。
答案 0 :(得分:1)
如果您可以使用固定时段并且不介意视图结果可能需要额外的磁盘空间,则可以创建每小时活动服务器的视图。
迭代开始和结束之间的时段,并在此期间发出每个服务器在线的时间:
function(doc) {
var start = new Date(doc.startTimestamp).getTime()
var end = new Date(doc.endTimestamp).getTime()
var msPerPeriod = 60*60*1000
var msOfflineInFirstPeriod = start % msPerPeriod
var firstPeriod = start - msOfflineInFirstPeriod
var msOnlineInLastPeriod = end % msPerPeriod
var lastPeriod = end - msOnlineInLastPeriod
if (firstPeriod === lastPeriod) {
// The server was only online within one period.
emit([new Date(firstPeriod), doc.serverName], [1, msOnlineInLastPeriod - msOfflineInFirstPeriod])
} else {
// The server was online over multiple periods.
emit([new Date(firstPeriod), doc.serverName], [1,msPerPeriod - msOfflineInFirstPeriod])
for (var period = firstPeriod + msPerPeriod; period < lastPeriod; period += msPerPeriod) {
emit([new Date(period), doc.serverName], [1, msPerPeriod])
}
emit([new Date(lastPeriod), doc.serverName], [1,msOnlineInLastPeriod])
}
}
如果您想要没有服务器名称的总数,只需使用内置快捷方式_sum
添加reduce函数。您将在此期间将在线服务器数量作为第一个数字和服务器在该时间段内联机的毫秒数作为第二个数字。
如果您将年,月和日作为第一个键,则可以使用视图。然后,您可以在查询时使用group_level来获得更精细或更粗略的概述。
请记住,此视图可能会在磁盘上变大,因为必须存储每一行,并且还会存储每个组级别的中间结果。因此,您不应将周期持续时间设置得太小 - 例如,每秒发出一行会占用大量磁盘空间。