Пагинация без сохранения состояния в CouchDB? - PullRequest
7 голосов
/ 21 июня 2010

Большинство исследований, которые я видел в отношении разбивки на страницы с CouchDB, показывают, что вам нужно взять первые десять (или сколько угодно) элементов из вашего поля зрения, затем записать документ docid последнего документа и передать его следующемустр.К сожалению, я вижу несколько вопиющих проблем с этим методом.

  • По-видимому, это делает невозможным пропуск в пределах набора страниц (если кто-то сразу перейдет на страницу 100, вам придется запуститьзапрашивает страницы 2-99, чтобы вы знали, как загрузить страницу 100).
  • Требуется, чтобы вы передавали много информации о состоянии между вашими страницами.
  • Трудно правильно кодировать,

К сожалению, мое исследование показало, что использование skip приводит к значительному замедлению для наборов данных 5000 записей или более, и может привести к серьезным последствиям, когда вы достигнете чего-то действительно огромного (страница 20000 с 10 записями на страницу может занять около 20 секунд - и да, есть большие наборы данных в производстве).Так что на самом деле это не вариант.

Итак, я спрашиваю: есть ли эффективный способ разбить результаты просмотра в CouchDB, который может получить все элементы с произвольной страницы?(Я использую couchdb-python , но, надеюсь, в этом нет ничего, что могло бы зависеть от клиента.)

Ответы [ 2 ]

3 голосов
/ 23 июня 2010

Я новичок в CouchDB, но думаю, что смогу помочь.Я прочитал следующее из CouchDB: Полное руководство :

Один недостаток разбиения на страницы в стиле связанного списка состоит в том, что ... переход на определенную страницу на самом деле не работает... Если вам действительно нужно перейти на страницу по всему диапазону документов ... вы все равно можете поддерживать индекс целочисленных значений в качестве индекса представления и использовать гибридный подход к решению разбиения на страницы.- http://books.couchdb.org/relax/receipts/pagination

Если я правильно понял, подход в вашем случае будет следующим:

  1. Вставьте числовую последовательность в ваш набор документов.
  2. Извлечение этой числовой последовательности в индекс числового представления.
  3. Использование арифметики для вычисления правильных начальных / конечных цифровых клавиш для вашей произвольной страницы.

Для шага 1,вам нужно добавить что-то вроде «page_seq» в качестве поля в ваш документ.У меня нет конкретной рекомендации о том, как вы получаете этот номер, и мне любопытно узнать, что думают люди.Чтобы эта схема работала, она должна увеличиваться ровно на 1 для каждой новой записи, так что последовательности СУБД, вероятно, отсутствуют (те, с которыми я знаком, могут пропускать числа).

Для шага 2 вы бынапишите представление с функцией карты, которая выглядит примерно так (в Javascript):

function(doc):
    emit(doc.page_seq, doc)

На шаге 3 вы напишите свой запрос примерно так (при условии, что последовательности page_seq и нумерации страниц начинаются с 1):

results = db.view("name_of_view")
page_size = ... # say, 20
page_no = ... # 1 = page 1, 2 = page 2, etc.
begin = ((page_no - 1) * page_size) + 1
end = begin + page_size
my_page = results[begin:end]

и затем вы можете перебирать my_page.

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

Комментарии / улучшения приветствуются.

1 голос
/ 22 октября 2010

Мы решили эту проблему, используя CouchDB Lucene для поиска в списках. Снимок версии 0.6 достаточно стабилен, вы должны попробовать его:

CouchDB Lucene репозиторий

...