1

我有具有时间值的记录,需要能够在一段时间内查询它们并仅返回给定时间间隔的记录。

例如,我可能需要每隔 10 分钟从 12:00 到 1:00 的所有记录,给我 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]) 
}

然后我创建了一个列表函数,它接受一个称为间隔的参数。在列表函数中,我通过行工作并将当前行时间与最后接受的时间进行比较。如果跨度大于或等于间隔,我将该行添加到输出并对其进行 JSON 化。

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}));
}

到目前为止,这运作良好。我将针对一些大数据进行测试,看看性能如何。关于如何更好地做到这一点的任何评论,或者这将是沙发的正确方式吗?

4

1 回答 1

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:30、00:45、00:50,那么只有 00:00、00 :30, 00:50 应该是最终结果。因此,您正在过滤正常的沙发输出以消除不需要的结果。对于一个函数来说,这是一个完美的工作_list。只需使用req.query.interval和仅send()匹配间隔的行。

于 2011-05-20T00:38:06.383 回答