Couchdb: фильтр и группа в одном представлении - PullRequest
4 голосов
/ 22 декабря 2010

У меня есть база данных Couchdb с документами в форме: {Name, Timestamp, Value}

У меня есть представление, которое показывает сводку, сгруппированную по имени с суммой значений.Это прямая функция уменьшения.

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

AFAIK, это означает, что я должен включить отметку временив испущенном ключе функции карты, например.emit([doc.Timestamp, doc.Name], doc)

Но как только я это сделаю, функция сокращения больше не видит строки, сгруппированные вместе, чтобы вычислить сумму.Если я поставлю имя первым, я могу сгруппировать только на уровне 1, но как фильтровать на уровне 2?

Есть ли способ сделать это?

Ответы [ 2 ]

1 голос
/ 04 января 2011

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

Если вы emit([time, name]), вы сможете запросить startkey=[timeA]&endkey=[timeB]&group_level=2, чтобы получить элементымежду timeA и timeB сгруппированы, где их отметки времени и имя были идентичны.Затем вы можете постобработать это, чтобы сложить всякий раз, когда имена совпадают, но начальный набор результатов может быть больше, чем вы хотите обработать.

Альтернативой будет emit([name,time]).Затем вы можете сначала выполнить запрос с помощью group_level=1, чтобы получить список имен [если ваше приложение еще не знает, какими они будут].Затем для каждого из них вы бы запросили startkey=[nameN]&endkey=[nameN,{}]&group_level=2, чтобы получить сводку для каждого имени.

(Обратите внимание, что в моих примерах запросов я оставил ключи JSON начала / конца незакодированными, чтобы сделать ихболее удобочитаемым, но вам нужно будет применить на вашем языке эквивалент JavaScript encodeURIComponent к ним при фактическом использовании.)

0 голосов
/ 03 марта 2011

Вы не можете сделать вид на вид. Вам нужно написать еще одно представление с уменьшением карты, которое имеет фильтрацию и в конце делает группировку. Что-то вроде:

map:
function(doc) {
  if (doc.timestamp > start and doc.timestamp < end ) {
    emit(doc.name, doc.value);
  }
}

reduce:
function(key, values, rereduce) {
  return sum(values);
}

Я полагаю, вы не можете сохранить это представление, и вам нужно поместить его как специальный запрос в ваше приложение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...