Функция CouchDB для выборки записей с заданным интервалом. - PullRequest
1 голос
/ 19 мая 2011

У меня есть записи со значением времени, и я должен иметь возможность запрашивать их за определенный промежуток времени и возвращать только записи с заданным интервалом.

Например, мне могут понадобиться все записи с 12:00 до 1:00 с 10-минутными интервалами, давая мне 12:00, 12:10, 12:20, 12:30, ... 12:5001:00Интервал должен быть параметром, и он может быть любым значением времени.15 минут, 47 секунд, 1,4 часа.

Я пытался сделать это с помощью какого-то сокращения, но это явно не то место, где можно это сделать.

Вот то, что я придумал.Комментарии приветствуются.

Создано представление для поля времени, чтобы я мог запрашивать диапазон времени.Представление выводит идентификатор и время.

function(doc) { 
  emit([doc.rec_id, doc.time], [doc._id, doc.time]) 
}

Затем я создал функцию списка, которая принимает параметр под названием интервал.В функции списка я работаю через строки и сравниваю текущее время строк с последним принятым временем.Если интервал больше или равен интервалу, я добавляю строку к выводу и 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}));
}

Пока это работает хорошо.Я протестирую некоторые большие данные, чтобы увидеть, как производительность.Любые комментарии о том, как это можно сделать лучше, или это будет правильный путь с диваном?

1 Ответ

1 голос
/ 20 мая 2011

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() строки, соответствующие интервалу.

...