поиск идей / альтернатив для предоставления страницы / количества элементов / навигации по элементам, соответствующим запросу хранилища данных GAE - PullRequest
9 голосов
/ 22 февраля 2012

Мне нравится простота хранилища данных, масштабируемость и простота использования;и улучшения, найденные в новой библиотеке ndb , просто невероятны.

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

Однако во многих приложениях, в том числе и в нашем, часто требуется увидеть количество подходящих элементов и предоставить пользователювозможность перехода на определенную страницу этих результатов.Проблема подкачки хранилища данных дополнительно усложняется требованием обойти ограничения fetch (limit, offset = X) , как описано в статье Пейджинг через большие наборы данных .Для поддержки рекомендуемого подхода данные должны включать однозначный столбец, который можно упорядочить по способу отображения результатов.Этот столбец будет определять начальное значение для каждой страницы результатов;сохранив его, мы можем эффективно извлечь соответствующую страницу, позволяя переходить к определенной или следующей странице по запросу.Поэтому, если вы хотите отображать результаты, упорядоченные несколькими способами, может потребоваться сохранить несколько таких столбцов.

Следует отметить, что начиная с SDK v1.3.1, Курсоры запросов являются рекомендуемым способом выполнения разбиения на страницы хранилища данных. У них есть некоторые ограничения, включая отсутствие поддержки операторов IN и! = фильтра.В настоящее время некоторые из наших важных запросов используют IN , но мы попробуем написать их, используя ИЛИ для использования с курсорами запросов.

Следуя предложенным рекомендациям, пользователь можетВам будут предоставлены (Next) и (Prev) навигационные кнопки, а также кнопки определенной страницы по мере навигации.Например, если пользователь нажал (Далее) 3 раза, приложение может отобразить следующие кнопки, запоминая уникальную начальную запись или курсор для каждой из них, чтобы обеспечить эффективную навигацию: (Пред.) (Page-1) (Страница-2) (Страница-3) (Страница-4) (Следующая) .

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

Мне нужны сведения об этих проблемах в целом и, в частности, следующие вопросы:

  1. Какие навигационные параметры результатов запросов вы предоставляете в своих приложениях хранилища данных для обхода этих проблем?ограничения?

  2. Если предоставление пользователям эффективного подсчета результатов и навигации по страницам всего набора результатов запроса является приоритетом, следует ли отказаться от использования хранилища данных в пользу GAE MySqlпредлагается решение .

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

Большое спасибо заранее за вашу помощь.

Ответы [ 4 ]

2 голосов
/ 23 февраля 2012

Все зависит от того, сколько результатов вы обычно получаете.Например, передавая .count () подходящий предел, вы можете указать точное количество, если #items, например, <= 100, и «много», если их больше.Похоже, вы не можете предварительно вычислить все возможные значения, но, по крайней мере, вы можете их кешировать, тем самым сохраняя множество операций хранения данных. </p>

Используя NDB, наиболее эффективным подходом может быть либо запрос первой страницы сущностей с использованиемfetch_page (), а затем используя результирующий курсор в качестве отправной точки для вызова count ();или, в качестве альтернативы, может быть лучше запустить fetch () первой страницы и count () одновременно, используя ее асинхронные средства.Второй вариант может быть вашим единственным выбором, если ваш запрос не поддерживает курсоры.Большинство запросов IN / OR в настоящее время не поддерживают курсоры, но они делают, если вы заказываете по __key__.

С точки зрения параметров пользовательского интерфейса, я думаю, достаточно предложить варианты для следующей и предыдущей страниц;пользовательский интерфейс "Gooooooogle", позволяющий пропускать несколько страниц, хорош, но я почти никогда не использую его сам.(Чтобы реализовать «предыдущую страницу», измените порядок запроса и используйте тот же курсор, который вы использовали для текущей страницы. Я почти уверен, что это гарантированно сработает.)

1 голос
/ 28 февраля 2012

Возможно, просто стремитесь к этому стилю подкачки:

(первый) (предыдущий) ( Page1 ) (страница2) (страница3) .... (последний) (следующий)

Таким образом, общее количество не требуется - вам нужен только ваш код, чтобы знать, что результатов достаточно для еще 3+ страниц.с размером страницы 10 элементов на страницу, вам просто нужно знать, что есть более 30 элементов.

Если у вас есть 60 элементов (достаточно для 6 страниц), когда вы уже находитесь на странице 4, ваш код будет с нетерпением ждатьи поймите, что осталось только 20 записей, поэтому вы можете показать номер последней страницы:

(первая) (Предыдущая) ( Page4 ) (Страница 5) (Страница 6) (следующая)) (последний)

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

Кроме того, если вы просто получите ключи, это будет более эффективно, чем получение дополнительных предметов.надеюсь, что это имеет какой-то смысл !! ​​??:)

0 голосов
/ 10 апреля 2015

Поскольку вопрос заключался в «поиске идей / альтернатив для предоставления страницы», может быть, очень простая альтернатива получения элементов key_only стоимостью 10 страниц, тогда стоит рассмотреть возможность навигации по этому набору.

Я подробно остановился на ответе на аналогичный вопрос, здесь вы найдете пример кода:

Разворот в обратном направлении с курсором работает, но отсутствует элемент

Пример кода будетбыть более подходящим для этого вопроса.Вот часть этого:

def session_list():
    page = request.args.get('page', 0, type=int)

    sessions_keys = Session.query().order(-Session.time_opened).fetch(100, keys_only=True)
    sessions_keys, paging = generic_list_paging(sessions_keys, page)
    # generic_list_paging will select the proper sublist.
    sessions = [ sk.get() for sk in sessions_keys ]

    return render_template('generic_list.html', objects=sessions, paging=paging)

Дополнительную информацию см. В указанном вопросе.

Конечно, если набор результатов потенциально огромен, некоторое ограничение на выборку все равно должно быть заданожесткий предел - 1000 пунктов, я думаю.Очевидно, что если в результате получается более 10 страниц, пользователю будет предложено уточнить, добавив критерии.

Работа с подкачкой в ​​нескольких сотнях элементов keys_only действительно намного проще, что она определенно стоитпринимая во внимание.Это позволяет довольно легко обеспечить прямую навигацию по страницам, как указано в вопросе.Фактические элементы сущности выбираются только для текущей текущей страницы, остальные - только ключи, поэтому это не так дорого.И вы можете рассмотреть возможность сохранения результирующего набора keys_only в memcache на несколько минут, чтобы пользователю, быстро просматривающему страницы, не потребовался повторный запрос.

0 голосов
/ 22 февраля 2012
  1. Я заметил, что gmail готов с некоторыми подсчетами - он может сказать вам, сколько всего электронных писем вы получили, и сколько находится в вашем почтовом ящике и т. Д. - но по другим показателям, например, при полнотекстовом поискеговорит, что вы смотрите "1-20 из многих" или "1-20 из примерно 130".Вам действительно нужно отображать счетчики для каждого запроса, или вы можете предварительно рассчитать только важные из них?
...