как получить n-ю запись запроса к хранилищу данных

Предположим, что у меня есть модель Foo в GAE и такой запрос:

запрос = Foo.all().order('-key')

Я хочу получить n-ю запись. Каков наиболее эффективный способ добиться этого?

Сломается ли решение, если свойство упорядочения не уникально, как показано ниже:

запрос = Foo.all().order('-цвет')

изменить: n > 1000

редактировать 2: я хочу разработать дружественный механизм пейджинга, который показывает доступные страницы (например, страница 1, страница 2,... страница 185) и требует "?page=x" в строке запроса вместо "?bookmark =ХХХ". Когда page = x, запрос состоит в том, чтобы получить записи, начиная с первой записи этой страницы.


person shanyu    schedule 05.05.2009    source источник


Ответы (2)


Эффективного способа сделать это нет ни в одной СУБД. В любом случае вы должны, по крайней мере, последовательно читать записи индекса, пока не найдете n-ю, а затем искать соответствующую запись данных. Это более или менее то, что делает fetch(count, offset) в GAE, с дополнительным ограничением в 1000 записей.

Лучший подход к этому — сохранить «закладку», состоящую из значения поля, которое вы упорядочиваете, для последнего извлеченного вами объекта и ключа объекта. Затем, если вы хотите продолжить с того места, на котором остановились, вы можете добавить значение поля в качестве нижней границы запроса неравенства и пропускать записи, пока не совпадете или не превысите последнее, что вы видели.

Если вы хотите предоставить пользователям «дружественные» смещения страниц, вы можете использовать кэш памяти для хранения ассоциации между начальным смещением и кортежем закладок (order_property, key). При создании страницы вставьте или обновите закладку для сущности, следующую за последней. Когда вы выбираете страницу, используйте закладку, если она существует, или создайте ее сложным способом, выполняя запросы со смещением — возможно, несколько запросов, если смещение достаточно велико.

person Nick Johnson    schedule 05.05.2009
comment
Извините, что я недостаточно разъяснил, что имел в виду. Пожалуйста, перепроверьте мой вопрос, я внес правку. - person shanyu; 06.05.2009
comment
Обновил мой ответ более подробно на этот счет. - person Nick Johnson; 06.05.2009

Документацию по классу Query можно найти по адресу: http://code.google.com/appengine/docs/python/datastore/queryclass.html#Query

Класс запроса обеспечивает выборку, которая принимает ограничение и смещение в вашем случае 1 и n

Время выполнения выборки растет линейно со смещением + предел

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

Вы можете использовать query.filter('key = ', n) query.get()

который вернет первое совпадение с ключом n

person user101852    schedule 05.05.2009
comment
Извините, что я недостаточно разъяснил, что имел в виду. Пожалуйста, перепроверьте мой вопрос, я внес правку. - person shanyu; 06.05.2009
comment
Вы не можете использовать фильтр по ключу для фильтрации по ключу — вы должны использовать псевдосвойство key. В любом случае такой фильтр не имеет смысла — он всегда будет возвращать только один результат, поэтому эффективнее будет использовать Model.get. - person Nick Johnson; 08.05.2009