Posts Tagged ‘Plugin’

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

Posted in Development, Dokuwiki, Sphinx Search on July 16th, 2010 by Yaroslav Vorozhko – Be the first to comment

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

Данные

Страницы dokuwiki хранятся в простых текстовых файлах. Каждый файл имеет свое уникальное название, называемое ID страницы. Обычно каждая страница содержит один или несколько разделов.
Проблема обычных плагинов поиска для DW, что они не учитываю разделы. А это, заставляет пользователя просматривать всю страницу целиком или делать внутренний поиск по странице, чтоб найти нужные данные. Я встречал страницы которые при печати на принтере занимали 15 страниц размера A4, попробуйте в таком документе найти что то.
Учитывая такое положение вещей нами была разработана система анализа страниц, которая выявляла секции документа. В дальнейшем каждая секция попадала в индекс как отдельный документ, что при поиске обеспечивало более точный результат и пользователь получал точную ссылку на секцию в документе.

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

Индексация

Для создания индекса Sphinx Search была применена технология xmlpipe2.
Специальный скрипт создает XML файл, который в свою очередь загружается в Sphinx индекс.
В процессе написания скрипта индексации мы столкнулись с одной проблемой: wiki страницы не имеют уникального цифрового идентификатора, без которого невозможно связать результаты поиска с конкретной страницой.
Для решение этой задачи в роли внешнего хранилища данных мы использовали SQLite.

Для каждой записи в индексе мы:

  1. создавали уникальный ID основанный на значении CRC32, взятого от имени страницы(внутреннего строкового ID)
  2. записывали связь индеска и страницы в 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. А также советую посетить официальную страницу плагина и больше узнать про его возможности.

Оживите свой Dokuwiki с помощью нового плагина поиска

Posted in Uncategorized on July 14th, 2010 by Yaroslav Vorozhko – 1 Comment

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

Один недостаток dokuwiki, который может перечеркнуть все плюсы удобства – это ее поиск. С ростом количества страниц вашей wiki базы, все труднее находить нужные документы.

Оригинальный поиск dokuwiki очень примитивен.

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

Альтернативой оригинальному поиску, может служить плагин Google Custom Search. Но, как и оригинальный поиск, Google поиск имеет множество ограничений:

  1. Вы отдаете свои данные Google, который может использовать их в других поисковых продуктах
  2. Google Custom Search может показывать рекламу на странице результатов, что может может негативно сказаться на репутации вашей компании
  3. Нет возможности проиндексировать недоступные публично страницы. Для любой компании сделать свою документацию публичной практически невозможно.
  4. Вы не можете контролировать релевантность результатов
  5. Вы не можете контролировать частоту переиндексации страниц, поэтому обновленная страница может не сразу попасть в поиск
  6. В Google Custom Search отсутствуют возможности фильтрации в пользовательском интерфейсе. Если вы незнакомы с синтаксисом Google поиска, тогда вы не сможете уточнить свой запрос

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

  1. Результаты поиска делятся не только по документам, а также и по разделам. Вам теперь не придется искать данные внутри одного большого документа, теперь ссылка ведет прямо на раздел, где содержиться искомый текст
  2. Мы сделали группировку результатов. Разделы одного документа группируются вместе, что значительно упрощает просмотр разделов документа
  3. Качественные результаты поиска благодаря Sphinx Search и возможности контролировать релевантность поисковых результатов
  4. Прорисовка разметки результатов и очистка от html тегов – в результатах только релевантный текст, никакой разметки
  5. Вы можете контролировать длину сниппетов – что упрощает беглое чтение результатов. Поставьте длину в 140 символов и результаты будет также легко читать как и твиттер.
  6. Удобная система фильтрации – фильтры по категориям значительно упрощают поиск документов
  7. Контроль уровня доступа, пользователь может искать только по тем документам для которых у него есть право на чтение
  8. Индекс находиться на вашем сервере – вы контролируете доступ к нему самостоятельно
  9. Переиндексацию индекса задаете с такой частотой, которая наиболее подходит для вашей wiki

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

Скачать последнюю третью версию можно с launchpad.  Более подробно узнать о возможностях плагина можно на официальной странице.

Sphinx Search плагин поиска для Wordpress – поиск с Sphinx Search для начинающих

Posted in PHP, Sphinx Search, WPSphinx plugin on December 23rd, 2009 by Yaroslav Vorozhko – 6 Comments

Два года назад Петр Зайцев из Percona попросил меня написать ему плагин поиска для WordPress используя Spinx Search. Сейчас этот модуль работает на mysqlperformanceblog.com.

Данная статья будет полезна тем кто только начинает знакомится с Sphinx Search. Ее можно использовать  как начальное руководство для написания простого поисковика на Sphinx Search.

Возможности плагина:

  • Быстрый поиск, ну это и понятно, мы ведь используем Sphinx Search
  • Возможность использовать расширенный синтаксис поиска (http://www.sphinxsearch.com/doc.html#extended-syntax)
  • Сортировка результатов поиска по дате или по релевантности
  • Поиск по постам, комментариям или страницам. Это отличает этот плагин от стандартного поиска на WP, который не производит поиск по комментариям и страницам. А также многие другие поисковые плагины не имеют такой возможности.
  • Есть возможность исключить из результатов поска комментарии, страницы или посты
  • И многие другие вкусности, про которые вы можете узнать на странице плагина

Все это позволяет нам делать Sphinx Search, и сейчас мы разеберем как это реализовано.

Конфигурационный файл

В первую очередь нам надо знать как устроен индекс. (sphinx.conf можно найти в каталоге rep/sphinx.conf)

Мы использовали самое простое решение это один монолитный индекс для всех данных: постов, страниц и комментариев. Формируется такой индекс единым SQL запросом, который приводить я тут не буду, он очень длинный и нас сейчас он не интересует (это все таки статья про Spihnx Search, а не про MySQL :) ), но посмотреть его можно в том же sphinx.conf.

Единственное, что нам стоит знать это какие атрибуты у нас есть:

  • comment_ID
  • post_ID
  • isPost
  • isComment
  • isPage
  • post_type
  • date_added

Атрибуты isPost, isComment и isPage отвечают за тип источника. date_added содержит дату добавления данных.

Поиск

Теперь рассмотрим как делать поиск, фильтрацию и сортировку используя атрибуты.
Пример:

CODE:
  1. if ( empty($this->params['search_comments']) ){
  2.     $this->config->sphinx->SetFilter('isComment', array(0));
  3. }
  4.                
  5. if ( empty($this->params['search_pages']) ){
  6.     $this->config->sphinx->SetFilter('isPage', array(0));
  7. }
  8.            
  9. if ( empty($this->params['search_posts']) ){
  10.     $this->config->sphinx->SetFilter('isPost', array(0));
  11. }
  12.        
  13.        
  14. if ( $this->params['search_sortby'] == 'date' ){ {
  15.     $this->config->sphinx->SetSortMode(SPH_SORT_ATTR_DESC, 'date_added');}
  16. } else {
  17.     $this->config->sphinx->SetSortMode(SPH_SORT_RELEVANCE);
  18. }
  19.  
  20. $res = $this->config->sphinx->Query ( $this->search_string, $this->config->admin_options['sphinx_index'] ););

Первое, если один из аттрибутов не установлен, то с помощью SetFilter('isPost', array(0)) мы исключаем его из поиска.
Второе, если пользователь захотел отсортировать результаты по дате добавления, то мы испольязем режим сортировки по атрибуту SetSortMode(SPH_SORT_ATTR_DESC, 'date_added'). По умолчанию данные сортируются по релевантности.
И последнее мы выполняем собственно запрос с помощью метода Query(), первый параметр это запрос введенный пользователем, второй это индекс по которому выполнять поиск.

Результат поиска

Результат поиска мы должны обработать следующим образом:

  • Получить найденный идентификационные номера и по ним получить данные
  • Используя атрибуты isPost, isPage и isComment мы узнаем из какой таблицы получать данные
  • Потом объединяем полученный результат
  • И последнее мы выделяем ключевые слова в результата, путем добавления html тэга STRONG вокруг слова.

Выделение ключевых слов делает метод BuildExcerpts

CODE:
  1. $opts = array(
  2.     'limit'  => $this->config->admin_options['excerpt_limit'],
  3.     'around' => $this->config->admin_options['excerpt_around'],
  4.     'chunk_separator' => $this->config->admin_options['excerpt_chunk_separator'],
  5.     'after_match' => $this->config->admin_options['excerpt_after_match'.$isTitle],
  6.     'before_match' => $this->config->admin_options['excerpt_before_match'.$isTitle]
  7. );
  8.                    
  9. $excerpts = $this->config->sphinx->BuildExcerpts(
  10.     $post_content,
  11.         'main_'.$this->config->admin_options['sphinx_index'],
  12.     $this->search_string,
  13.     $opts
  14. );

В параметрах этого метода надо указать строку результата в которой надо выделить слова, индекс, запрос и параметы выделения.  В результате мы получем строку с подсвеченными ключевыми словами, которые пристуствовали в запросе.

В итоге как мы видим, написать свой поиск используя Sphinx Search достаточно просто. Если у вас большой блог и вы также хотите получить быстрый и много-функциональный поиск, тогда скачивайте WPSphinx плагин - это бесплатно. :)