2010-12-22 3 views
3

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

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

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

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

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

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

ответ

1

Я не думаю, что это возможно с использованием только одной 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, чтобы сделать их более удобными для чтения, но вам необходимо применить эквивалент вашего языка encodeURIComponent на них в реальном использовании .)

+0

Это правда? Кажется, я не могу заставить его работать. –

+0

Может быть. Я исправил одну ошибку в моем примере (вам нужно исправить массив), что может помочь. Однако, похоже, мое описание того, как результат группируется, также может вводить в заблуждение, я попробую пересмотреть следующий. – natevw

-2

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

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

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

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

Смежные вопросы