couchdb - пересортировать результат в уменьшенном виде - PullRequest
1 голос
/ 10 января 2012

Рассмотрим следующие структуры документов:

Тема:

 - doc_type   1
 - _id        
 - subject    (string)

Сообщений:

 - doc_type   2
 - _id        
 - thread_id  (_id of Thread)
 - time       (milliseconds since 1970)
 - comment    (string)

Iнужны темы, отсортированные по последнему сообщению в теме, вместе с последними 5 сообщениями.Я подумал, чтобы не обновлять документ потока каждый раз, когда создается новая запись, чтобы исключить вероятность конфликтов в распределенной среде между узлами БД.Кроме того, он будет работать для БД, где БД должна работать для вас.

Для простоты - давайте просто начнем с поиска последней записи.5 сообщений можно собрать одинаково.

Теперь я не уверен, что нахожусь в правильном направлении, однако, глядя здесь Я нашел, как найти последний пост впоток, использующий функцию приведения, который использует групповой уровень для возврата темы потока, взятой из doc-типа 1, и последний пост-документ, взятый из doc-типа 2.

BTW - в отличие от образца в ссылкев моем случае тема всегда создается с первым сообщением (например, датой создания темы будет дата ее первого сообщения).

map:

function(doc){
  switch(doc.doc_type){
     case 1: emit([doc._id],doc); return;
     case 2: emit([doc.thread_id],doc); return;
  }
}

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

function(keys, vals, rr){
   var result = { subject: null, lastPost: null, count :0 };
   //I'll ignore the re-reduce case for simplicity
   vals.forEach(function(doc){
      switch(doc.doc_type){
         case 1: 
            result.subject = doc.subject; 
            return;
         case 2: 
            if (result.lastPost.time < doc.time) result.lastPost = doc; 
            result.count++;
            return;
      }
   });
   return result;
}

Но как мне страница впоследствии отсортировать по дате последней публикации ?Есть ли способ подачи идентификаторов документов из результата запроса в качестве критерия фильтра другого (предпочтительно с использованием одного и того же запроса)?

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

Кто-нибудь?

1 Ответ

1 голос
/ 25 января 2012

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

Если вы добавите время в качестве второй части ключа, вы можете использовать комбинацию конечного ключа, убывания и ограничения, чтобы получить последние N сообщений, основанные на идентификаторе потока.

Вот MapReduce, который я написал с некоторыми тестовыми данными, основанными на ваших схемах:

function(doc) {
  if (doc.type) {
    if (doc.subject) {
      emit([doc._id, doc.time], doc.subject);
      emit([doc._id, 'Z'], doc.subject);
    } else {
      emit([doc.thread_id, doc.time], {_id: doc._id});
    }
  }
}

Странный вывод клавиши 'Z' состоит в том, что вы можете получить предмет из "нижней части" списка предметов.

Параметры запроса будут выглядеть примерно так:

?endkey=["thread_id"]&descending=true&limit=6

Ограничение должно составлять N + 1, где N - количество сообщений, которые вы хотели бы вернуть. В результате вы получите тему темы и _id объекты (или все, что вам нужно) из почтовых документов.

Объекты _id выводятся в этом примере, так что вы можете использовать его с include_docs=true, если вы хотите полный пост. Добавьте все остальные данные из почтового документа, который вы хотите (заголовок и т. Д.), Чтобы общий размер индекса оставался низким, и используйте include_docs в тех местах, где вам нужно полное содержимое документа. Однако, если вам всегда нужен полный пост-документ, выведите его в emit, поскольку это даст вам более быстрый отклик (хотя и больший размер индекса на диске).

Кроме того, если вам нужен список всех тем, отсортированных по последнему сообщению, а также 5 сообщений в теме, вам необходимо вывести такие ключи, как [time, thread_id, 'thread'] и [time, thread_id, 'post'] и использовать _list для сбора сообщений. «под» каждым документом цепочки, поскольку сортировка по времени приведет к тому, что потоки и сообщения будут отделяться друг от друга в результатах. Затем можно использовать функцию _list, чтобы снова их объединить / найти. Однако выполнение двух запросов все еще может быть проще / легче.

...