我有时间值的记录,需要能够在一段时间内查询它们,并且只返回给定间隔的记录。
例如,我可能需要从12点到1点的所有记录,每隔10分钟给我12:00,12:10,12:20,12:30,... 12:50,01: 00。间隔需要是一个参数,它可以是任何时间值。 15分47秒1.4小时。
我尝试做某种减少,但这显然是错误的做法。
这是我想出的。欢迎评论。
为时间字段创建了一个视图,以便查询一系列时间。视图输出id和时间。
function(doc) {
emit([doc.rec_id, doc.time], [doc._id, doc.time])
}
然后我创建了一个列表函数,它接受一个名为interval的参数。在list函数中,我通过行工作并将当前行的时间与最后接受的时间进行比较。如果跨度大于或等于间隔,我将行添加到输出中,并将JSON-ify添加到输出中。
function(head, req) {
// default to 30000ms or 30 seconds.
var interval = 30000;
// get the interval from the request.
if (req.query.interval) {
interval = req.query.interval;
}
// setup
var row;
var rows = [];
var lastTime = 0;
// go thru the results...
while (row = getRow()) {
// if the time from view is more than the interval
// from our last time then add it.
if (row.value[1] - lastTime > interval) {
lastTime = row.value[1];
rows.push(row);
}
}
// JSON-ify!
send(JSON.stringify({'rows' : rows}));
}
到目前为止,这种方法运作良好。我将针对一些大数据进行测试,以了解性能如何。关于如何更好地完成这项工作的任何意见,或者这是否是沙发的正确方法?
答案 0 :(得分:1)
CouchDB很放松。如果这对您有用,那么我会坚持下去并专注于您的下一个优先事项。
一个快速优化是尽量不在_list
函数中建立最终答案,而是在你知道的答案的send()
小部分。这样,您的函数可以在无限的结果大小上运行。
但是,正如您所怀疑的那样,您基本上使用_list
函数进行即席查询,这可能会因您的数据库大小增加而出现问题。
我不是100%确定你需要什么,但如果你在一个时间范围内寻找文件,那么emit()
密钥很可能主要按时间排序。 (在您的示例中,主要(最左侧)排序值为doc.rec_id
。)
对于地图功能:
function(doc) {
var key = doc.time; // Just sort everything by timestamp.
emit(key, [doc._id, doc.time]);
}
这将构建按time
时间戳排序的所有文档的地图。 (我假设时间值类似于JSON.stringify(new Date)
,即"2011-05-20T00:34:20.847Z"
。
要查找1小时内的所有文档,只需使用?startkey="2011-05-20T00:00:00.000Z"&endkey="2011-05-20T01:00:00.000Z"
查询地图视图。
如果我正确理解你的“间隔”标准,那么如果你需要10分钟的间隔,那么如果你有00:00,00:15,00:00,00:45,00:50,那么只有00: 00,00:00,00:50应该在最终结果中。因此,您过滤正常沙发输出以消除不需要的结果。对_list
函数来说,这是一个完美的工作。只需使用req.query.interval
并且仅send()
匹配间隔的行。