Разбиение на страницы не сохраняющее состояние в CouchDB?

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

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

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

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

7
задан LeafStorm 21 June 2010 в 01:50
поделиться

1 ответ

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

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

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

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

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

Для шага 2 вы бы написали представление с функцией map, которая выглядит примерно так (на 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 предполагает, что вы не фильтруете набор данных для вашего представления, и вы быстро столкнетесь с проблемами, если попытаетесь заставить это работать с произвольным запросом.

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

3
ответ дан 7 December 2019 в 14:29
поделиться
Другие вопросы по тегам:

Похожие вопросы: