суббота, 17 июля 2010 г.

Детали разработки плагина поиска для Dokuwiki

custom-windows-mobile-development1В этой статье я расскажу некоторые подробности реализации нашего плагина поиска для Dokuwiki. Я постарался сделать описание как можно более понятным и развернутым. Главное вы узнаете как применяя простые техники можно создать отличную поисковую систему для dokuwiki.

Вы можете скачайте исходники с launchpad – они помогут вам лучше разобраться в плагине.


Данные


Страницы dokuwiki хранятся в простых текстовых файлах. Каждый файл имеет свое уникальное название, называемое ID страницы. Обычно каждая страница содержит один или несколько разделов.

Проблема обычных плагинов поиска для DW, что они не учитываю разделы. А это, заставляет пользователя просматривать всю страницу целиком или делать внутренний поиск по странице, чтоб найти нужные данные. Я встречал страницы которые при печати на принтере занимали 15 страниц размера A4, попробуйте в таком документе найти что то.

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


Я бы с удовольствием привел бы код анализа wiki документов, но его описание и длина займет пару страниц. Просто скачайте исходники из launchpad и посмотрите функцию getSectionByTitleLevel в файле functions.php


Индексация


Для создания индекса Sphinx Search была применена технология xmlpipe2.

Специальный скрипт создает XML файл, который в свою очередь загружается в Sphinx индек.

В процессе написания скрипта индексации мы столкнулись с одной проблемой – wiki страницы не имеют уникального цифрового идентификатора, а без цифрового идентификатора невозможно связать результаты поиска с конкретной страницой.

Решение было использовать внешнее хранилище данных, а именно SQLite. Для каждой записи в индексе мы создавали уникальный ID основанный на CRC32 от имени страницы(внутреннего строкового ID), и записывали связь индеска и страницы в SQLite базу.


Структура XML файла имеет следующий вид:

<?xml version=”1.0″ encoding=”utf-8″?>

<sphinx:docset>


<sphinx:schema>

<sphinx:field name=”title”/>

<sphinx:field name=”body”/>

<sphinx:field name=”namespace”/>

<sphinx:field name=”pagename”/>

<sphinx:field name=”level”/>

<sphinx:field name=”modified”/>

<sphinx:attr name=”level” type=”int” bits=”8″ default=”1″/>

</sphinx:schema>


Как видите она очень простая. Первые четыре поля самые важные – они отвечают за весь поиск.

По полям namespace и pagename производиться подстрочный поиск. По полям body и title производиться поиск на точное совпадение.

Больше информации о поиске можно получить из файла sphinx.conf, который также находиться в пакете плагина.


Поиск


Оригинальный поиск DW примитивен и содержит много недостатков, который я описал в предыдущей статье.

В нашем плагине мы сделали много улучшений по сравнению с обычным поиском.

Я расскажу про 3 основных:



  1. Группы результатов

  2. Прорисовка разметки результатов

  3. Фильтры по пространству имен (namespaces)


Группы результатов


При тестировании мы обнаружили, что иногда большие документы у которых много разделов, при поиске, могут занять первые 5, а то и 10 позиций. Чтоб избежать такого спама страницы результатов, мы объединили результаты с одного документа в группу. Скажу честно эта идея была взята у Google, когда результаты с одного домена группируются вместе.


Прорисовка разметки результатов


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

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


Для прорисовки секции использовали следующую конструкцию:


p_render(’xhtml’,p_get_instructions(getSectionByTitleLevel($data['page'], $data['title'], true)),$info);

getSectionByTitleLevel($data['page'], $data['title'], true) – согласно названии функции возвращает разметку конкретной секции внутри документа.

Прорисовка страницы целиком производиться проще:


p_wiki_xhtml($data['page'])

$data[‘page’] – это ID имя страницы


Фильтры по пространству имен (namespaces)

Одна из новых возможностей, которой нет ни в одном поисковом плагине для DW – это фильтр результатов поиска по пространству имен. Sphinx Search предоставляет большие возможности по обработке данных поиска. Используя расширенный синтаксис поиска мы создали следующие запросы:

1. Простой запрос по ключевому слову

(@(namespace,pagename) $starKeyword) | (@(body,title) {$keywords})

2. Запрос с фильтром по namespace

(@(namespace,pagename) {$categories}) & ((@(body,title) {$keywords}) | (@(namespace,pagename) {$starKeyword}))

3. Запрос по Matching Pagenames без фильтра по namespace

(@(namespace,pagename) $starKeyword)

4. Запрос по Matching Pagenames с фильтром по namespace

(@(namespace,pagename) $categories $starKeyword)


$keywords – это заданные ключевые слова

$starKeyword – это ключевые слова слева и справа которых добавлены звездочки для поиска в подстроках. Например: *hotel*.

$categories – это заданное пространство имен по которому необходимо ограничить поиск


Пару слов о внешнем виде


Также мы хорошо поработали над юзабилити. Мы изменили стандартные dokuwiki стили результатов поиска на Googl-like стили.

Смотрите как ужасно выглядит страница результатов в оригинальном поиске:


Original ugly dokuwiki search


А теперь сравните с стилями применяемыми в нашем плагине. Все просто и понятно, а также они очень хороши для чтения.


Nice Sphinx Search Dokuwiki search





Уже только ради внешнего вида стоит попробовать наш плагин поиска.


На данный момент, мы уже выпустили третью версию плагина, который вы можете бесплатно скачать на launchpad. А также советую посетить официальную страницу плагина и больше узнать про его возможности.




© Yaroslav Vorozhko for Просто про веб технологии, 2010. |
Permalink |
No comment |
Add to
del.icio.us


Post tags: Dokuwiki, Ivinco, Plugin, search, Sphinx Search




Комментариев нет:

Отправить комментарий