Я пишу приложение на основе GAE, которое должно позволять пользователям фильтровать элементы по нескольким их свойствам. Элементы хранятся как объекты NDB. Некоторым реквизитам можно сопоставить стандартные фильтры запросов, но для некоторых требуется «полный» (подстрочный) текстовый поиск, чтобы все это имело смысл. Кроме того, требуется разумный порядок. Возможно, лучше всего это проиллюстрировано следующим надуманным примером:
class Product(ndb.Model) :
manufacturer = ndb.StringProperty()
model = ndb.StringProperty()
rating = ndb.IntegerProperty(choices = [1, 2, 3, 4])
features = ndb.StringProperty(repeated = True, choices = ['feature_1', 'feature_2'])
is_very_expensive = ndb.BooleanProperty()
categories = ndb.KeyProperty(kind = Category, repeated = True)
Все сущности продукта имеют того же предка, что и их «контейнер». Товар может принадлежать к одной или нескольким категориям, а последние образуют дерево.
Теперь пользователи должны иметь возможность:
- Сузьте список продуктов, выбрав категорию (достаточно одной)
- Отфильтруйте их, указав минимальный рейтинг и желаемые функции.
- Просмотреть исключительно товары, которые очень дорогие или те, которые не очень (или просмотреть все)
- Поиск товаров по фрагменту текста из полей модели и/или производителя
- Заказывайте окончательный список, например. по названию модели (возможность выбрать заказ была бы идеальной).
Все это одновременно, т.е. фильтры и упорядочивание должны беспрепятственно применяться при предоставлении условий поиска.
Вопрос в следующем: как реализовать такую функциональность с помощью GAE?
В базе данных будут сотни тысяч или, возможно, миллионы товаров. Проблема с API поиска при использовании вместе с запросами NDB заключается в фильтрации результатов поиска и, возможно, их упорядочении.
Два решения, о которых я думал:
Добавьте повторяющееся
StringProperty
в модельProduct
, которая будет содержать все доступные для поиска подстроки (или, по крайней мере, префиксы) слов из полейmanufacturer
иmodel
. Это просто и работает, но я серьезно обеспокоен производительностью. В моих экспериментах я получал в среднем 40-50 доступных для поиска префиксов слов для каждого "Product
".Используйте Search API исключительно для этой задачи, применяя расширенные поисковые запросы. Например. я могу хранить категории продуктов (в виде идентификаторов или путей) в отдельном поле документа и использовать это поле для получения продуктов, принадлежащих к данной категории. Вероятно, это можно сделать, но меня здесь беспокоит ограничение в 10 000 результатов поиска и различные ограничения / квоты использования. Я также не уверен в порядке результатов.
Есть ли другие способы?