CouchDB - Лучшие N документов для каждой группы - PullRequest
2 голосов
/ 22 сентября 2011

Сейчас я оцениваю CouchDB, пройдясь по паре общих случаев использования, с которыми мы столкнемся в нашем веб-проекте.

Один из этих вариантов использования следующий:

Рассмотрим систему, содержащую (надуманный пример):

  • Статья
  • вопросы
  • 1012 * Темы *

статьи и вопросы могут быть назначены на несколько тем.

У темы есть своя страница (подумайте о http://www.quora.com темах).

Можно ли одним запросом от couchdb получить ОБА:

  • последние N статей по теме X
  • И последние N (или М?) Вопросов по теме X

В более общих терминах: я ищу способ сделать группу по типу (где, в данном случае, type = 'article' или 'question') и для каждой группы вернуть первые n документов с учетом определенного сортировка (в данном случае сортировка в обратном хронологическом порядке) ограничена определенным фильтром (в данном случае тема «X»)

Из того, что я прочитал, часто не так уж сложно делать несколько запросов couchdb параллельно с точки зрения производительности, но мне просто любопытно, можно ли использовать этот (для нас часто используемый) вариант использования сделано в одном запросе.

Спасибо за понимание

Ответы [ 2 ]

1 голос
/ 23 сентября 2011

номер

Представления CouchDB являются одномерными. Для данной темы самые последние статьи И самые последние вопросы - это двумерный запрос, и поэтому он невозможен в одном HTTP-запросе.

Мысли об обходном пути

CouchDB предназначен для параллельных запросов и поддерживает их. На производстве я бы сделал два запроса из другого ответа одновременно. (В Javascript это очень просто, но любой асинхронный или многопоточный язык программирования может это сделать.)

Время отклика для получения обоих результатов будет только временем отклика для более длинного результата (т. Е. Тот, который заканчивался первым, был "свободным"). Вы даже можете пройтись по строкам обоих ответов , чтобы объединить их временные шкалы в пространстве O (1) и времени O (n) - неплохо!

Единственное, что CouchDB не гарантирует, это то, что оба запроса представляют собой снимки одного и того же состояния базы данных. Вы упоминаете Quora, и это прекрасный пример современных требований к базам данных. В теории вы не представляете, насколько сильно изменилось состояние базы данных между этими двумя запросами. Как правило, вы понятия не имеете, имеет ли смысл какое-либо представление по сравнению с другим. На практике ответ очевиден: Кого это волнует? Запросы, разделенные простыми миллисекундами, в действительности будут иметь смысл вместе. Вот почему CouchDB хорошо подходит для веб-приложений, несмотря на наличие строго ограниченного набора функций.

Альтернативное решение: GeoCouch

Расширение GeoCouch на самом деле представляет собой универсальный двухмерный механизм запросов ограничивающего прямоугольника. Помимо, очевидно, геопространственных данных, их можно использовать, например, для запроса журналов, хранящихся в виде timestamp x severity 2-пространства. Однако в настоящее время это все еще отдельный проект от CouchDB, поэтому я бы не хотел называть его «запросом CouchDB».

0 голосов
/ 22 сентября 2011

С одним запросом из CouchDB можно получить оба.В обоих запросах используется запрос сопоставления / уменьшения, хотя вам не нужна функция сокращения.

В строках представления должно быть [$type, $topic, $timestamp] пар для ключей:

["article" , "money", "2011-09-21T20:50:29.819Z"]
["article" , "shoes", "2011-09-21T20:30:29.819Z"]
["article" , "shoes", "2011-09-21T20:50:29.819Z"]
["question", "grits", "2011-01-13T20:30:18.123Z"]
["question", "money", "2011-09-20T20:30:18.123Z"]

Эта функция можетсделайте это:

function(doc) {
    // _design/my_app/_view/topic_parts
    var key;

    if(doc.type && doc.parent_topic && doc.created_at) {
        // Looks good, emit it into the view.
        key = [doc.type, doc.parent_topic, doc.created_at];
        emit(key, doc);
    }
}

Чтобы найти последние N строк (будь то статьи или вопросы), вам, в основном, нужны строки, соответствующие [$type, $topic, *] в порядке убывания.Например, для последних N статей по теме X это выглядит следующим образом.(Обратите внимание, что null является наименьшим значением в CouchDB, а объект {} является самым большим.)

  • descending=true, чтобы получить обратный хронологический порядок.(Обратите внимание, что «нисходящий» концептуально означает, что кушетка сканирует «снизу» до «верха» строк. * startkey и endkey меняются местами .)
  • startkey=["articles","X",{}], поэтомуэто статьи о X начиная с конца времени
  • endkey=["articles","X",null], это те же самые статьи о X заканчивая началом времени
  • limit=N, чтобы урезать результаты до

Таким образом, запрос будет выглядеть следующим образом (не забывайте кодировать URL при необходимости).

GET /db/_design/my_app/_view/topic_parts?descending=true&startkey=["articles","X",{}]&endkey=["articles","X",null]&limit=N
...