1f190833

ПОИСК


В Zope есть встроенный механизм поиска - ZCatalog. Он не работает с морфологией, не ищет по регулярным выражениям. Что-то вроде htDig, к которому не прикрутили морфологию. Но! Есть у Z-Каталога одно большое достоинство - тесная интеграция с Zope. Я могу индексировать только определенные объекты, по дате, могу ограничиться только объектами, для которых у роли X есть право доступа Y и т.п. Кроме того, после индексации объекты сами говорят своим каталогам "я изменился - переиндексируй меня", о чем в htDig приходится только мечтать. Аналогично и при добавлении новых объектов и удалении старых - они посылают сообщение каталогу. Точнее, могут посылать - для этого их классы надо наследовать от CatalogAware.

Для начала работы надо добавить на сайт экземпляр или несколько экземпляров класса ZCatalog. Я добавил 1 в корень, и назвал его search-catalog. Затем сайт первый раз индексируется. Я проиндексировал полностью все объекты, у которых Anonimous имеет право View - хочу сделать публичный поиск. В процессе индексации Z-Каталог создает несколько индексов. Какие именно - дело менеджера. Я не стал менять умолчания, и поэтому у меня создались:

  • текстовый индекс для полнотекстового поиска по содержанию
  • текстовый индекс для поиска по атрибуту title каждого объекта

и еще несколько, которые здесь неинтересны.

Форму для поиска я загнал в отдельный мелкий Метод , для того, чтобы иметь одну копию формы (с параметрами - показывать ли кнопку "Искать", и размер поля ввода), а саму форму вставлять в разные места.

Первое место, где эта форма используется - отдельная страница поиска . Устроена она просто:

. Стандартное оформление плюс вызов упомянутого Метода с параметром "показать кнопку".

Сам поиск реализован на DTML же... ну то есть на DTML написан вызов Z-Каталога и оформление результатов:

.

Сначала я получаю ссылку на сам объект каталог: catalog=_.getitem('search-catalog', 0), затем проверяю, был ли передан в форме параметр text_search. Если да - делаю 2 поиска по каталогу - по содержимому текстов (индекс PrincipiaSearchSource) и по заголовкам (индекс title).
Результаты двух поисков склеиваю - это такой способ выполнить операцию OR. Операция AND поддерживается в таком виде: catalog(id="index_html", title="Python"). О памяти/скорости не беспокоюсь - ZCatalog полностью поддерживает lazy evaluation, и даже суммирование результатов не заставляет его грузить в память все объекты. Если text_search не было - просто делаю пустой запрос к каталогу; при этом найдутся все объекты. Ну и выдача результирующего HTML - простой цикл по списку результатов с разбивкой на страницы. Текстовая версия тоже работает. Работает как переход их полной версии в текстовую, так и версия для распечатки, причем ссылки из текстовой версии результатов поиска честно ведут на текстовые версии документов. Я почему это подчеркиваю? Да потому что я потратил на текстовую версию не больше полчаса, и с тех пор пользуюсь результатами. Плюс еще минут 10 я потратил, чтобы передать запрос на странице результатов поиска в ссылки на текстовые и печатные версии.

Содержание раздела