« Поставить закладку » « Сделать стартовой »

« Форумы » « Блоги » « Статьи » « Новости » « Файлы » « Realcoding IRC » « Site map » « Поиск »


Главная Главная
Анонсы Анонсы
Форумы Форумы
Каталог Каталог
Поиск Поиск
Опросы Опросы
Книжный магазин Книжный магазин
Реклама на сайте
Публикации Публикации
Партнеры Партнеры
Карта Карта сайта
Рассылки Рассылки
RSS экспорт
Настройки Настройки
О нас пишут О нас пишут
Контакты Контакты
Гостевая книга Гостевая книга


ПнВтСрЧтПтСбВс
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31        
    Популярное
Функция AccessResource

Упрощаем работу с потоками (TStream)

Типы блокировок

Системный реестр

C++ Builder Работа с базой данных через ADO

IDE

Броузеры, которые мы выбираем

Создание настроек и Мастеров для Visual Studio .NET

Как подготовить удачное резюме

ГЛАВА 8. Принципы построения графического интерфейса




    Архив файлов



    Сообщества

    Документация

    Кто на сайте
Вы не зарегистрированы.
Имя:

Пароль:

Запомнить

Регистрация позволит Вам пользоваться дополнительными сервисами.
Сейчас на сайте:
Гостей: 189
Пользователей: 1
  • admin

  • Статьи:: Интернет технологии :: PHP :: Яндекс-like поиск своими руками



    отправить ссылку другу версия для печати  Обсудить на форуме

    Яндекс-like поиск своими руками

    Редкий веб-программист не сталкивался с задачей написания поиска для своего сайта. Независимо от того – делалось ли это для собственной CMS или для первого сайта, сделанного фирме двоюродного дяди топориком на коленке в 10 классе.



    Зачастую, задача поиска по сайту решается использованием простого SQL-запроса вида where `content` like ‘%семенович%’, при котором искомая фраза разбивается на слова и каждое ищется средствами SQL среди строк в БД. Несмотря на простоту этого решения, качество результатов такого поиска оставляет желать лучшего. Ответственные разработчики используют индексацию, учитывают релевантность и даже морфологию. Однако ещё ни на одном сайте я не видел такого красивого поиска, как на Яндексе.

    Что я сейчас понимаю под красивым поиском:

    * Сортировка результатов по релевантности
    * Учёт морфологии русского языка
    * И самое главное – функцию «возможно вы искали»


    Можно ли сделать такой поиск на своем сайте, затратив совсем немного времени и не используя громоздкие базы словоформ? Можно.

    Сразу должен предупредить – это не описание того, как работает поиск на Яндексе. Это описание того, как сделать поиск, на 80% похожий на поиск в Яндексе:) Другими словами – будут показаны те методы, которые дают максимальную эффект при минимальных трудозатратах.

    1. Сортировка по релевантности.

    «Релевантность - субъективное понятие, выражающее степень соответствия запроса и найденного, уместность результата» (Wikipedia).
    Поскольку понятие субъективное, значит и определять его придется нам самим. Сделаем релевантность документа функцией двух параметров – числа слов запроса, которые присутствуют в документе, и количества вхождений всех этих слов в текст.

    Например, запрос «компьютерные салоны Сыктывкара».
    В тексте «компьютерные» присутствует 5 раз, «салоны» 2 раза, «Сыктывкар» - 0 раз. У нас встретилось 2 слова, и всего 7 их вхождений. На языке математики x=2, y=7.
    Определим функцию релевантность(x,y) = 1000x + y.
    При таком ранжировании выше окажутся те страницы, в которых встречается больше слов из запроса, а между собой они будут отсортированы по частоте вхождения данных слов.

    При правильно построенном индексе сайта, сортировку по релевантности можно легко включать прямо в SQL запрос, использовав order by (технические подробности ниже).

    2. Учет морфологии русского языка.

    Под поиском с морфологией понимают поиск, который не чувствителен к форме слова, то есть ищет не только «соседей», но и «соседи», «сосед», «соседский» и так далее.
    Добиться этого можно двумя путями – правильным и «почти правильным».

    Правильный путь заключается в наличии огромного (порядка 50 мб) словаря словоформ, грамотно переведенного в формат используемой БД и прикрученный к «движку» сайта. Найти бесплатный словарь можно тут: Ispell dictionary list, правда придется разбираться с его структурой.

    «Почти правильный» путь – выделять корень слова на основе общих лингвистических правил языка (отбрасывая стандартные суффиксы и окончания). Делается это при помощи «стеммера». (Исходный код стеммера для языка PHP).
    Минус этого алгоритма в том, что он основан на правилах. А как известно, у каждого правила есть исключения – данный алгоритм бессилен против пар вроде «идти»-«шёл», а также непредсказуем в случае с беглыми гласными, довольно часто встречающимися в русском языке (лев-львов, овца-овец).

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

    3. Функция «возможно вы искали».

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

    Как же нам поправить человека, который ввел «малако» вместо «молоко»?

    Для английского языка давно существует алгоритм soundex, который устанавливает одинаковый индекс для строк, имеющих схожее звучание.
    В MySQL и PHP функция soundex является встроенной. Работает ли она для русских слов? Нет, она работает только со словами, записанными латинскими буквами. Однако ничто не мешает нам записать наши русские слова латинскими буквами!
    То есть переводим слово в транслит (не общепринятый транслит, а более подходящий именно по звучанию) и сразу же можем применять soundex.

    К слову, существует попытка реализации русской версии soundex. Правда основана она на все той же soundex, только предварительно происходит учёт звучания русских букв.

    При индексации слова находим его sound index и записываем в базу данных рядышком с корнем. При поиске отмечаем те слова из запроса, которые не были найдены ни в одном документе, и только для них производим поиск близкого по звучанию аналога (если найдено несколько - отбираем самое часто встречающееся на сайте). Если такое слово найдено - выводим подсказку.

    4. Техническая реализация.

    (Реализация на языке PHP для MySQL.)

    Структура таблиц в базе данных.

    CREATE TABLE `indexing_link` (
    `id` int PRIMARY KEY auto_increment,
    `url` varchar(255) not null default '',
    `title` varchar(255) not null default '',
    `short` text not null default ''
    );

    CREATE TABLE `indexing_word` (
    `id` int PRIMARY KEY auto_increment,
    `word` varchar(30) not null default '',
    `sound` char(4) not null default 'A000'
    );
    CREATE INDEX idx_word_word ON indexing_word ( word(8) );
    CREATE INDEX idx_word_sound ON indexing_word ( sound(4) );

    CREATE TABLE `indexing_index` (
    `id` int PRIMARY KEY auto_increment,
    `link` int not null default 0,
    `word` int not null default 0,
    `times` int not null default 0
    );
    CREATE INDEX idx_index_linkword ON indexing_index (link, word);

    Таблица link содержит список документов в виде ссылки, заголовка и анонса (первых 300 символов страницы для вывода в результатах поиска).

    Таблица word – содержит слова и включает в себя word – то что осталось после стеммера (то что мы называли «корнем») и sound – результат функции soundex для данного слова.

    Таблица index связывает две других таблицы. Каждая ее строка – это слово «word», встретившеея на странице «link» «times»-раз.

    Индексация.

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

    $tex = preg_replace('@<script[^>]*?>.*?</script>@si',' ',$tex);
    $tex = preg_replace('@<style[^>]*?>.*?</style>@si',' ',$tex);
    $tex = preg_replace('@<[/!]*?[^<>]*?>@si',' ',$tex);

    Для повышения качества поиска, можно предварительно выделять слова, заключенные в тэги title, h1-h6, b, strong, em, meta keywords и description, и повышать их вес в индексе для данной страницы. Например, банально умножив число вхождении этих слов на 3.

    Стеммер.

    Код стеммера можно взять тут - Эвристическое извлечение корня из русского слова

    Транслитерация:

    function rus2lat($string){
    $rus = array('ё','ж','ц','ч','ш','щ','ю','я','Ё','Ж','Ц','Ч','Ш','Щ','Ю','Я','Ъ','Ь','ъ','ь');
    $lat = array('e','zh','c','ch','sh','sh','ju','ja','E','ZH','C','CH','SH','SH','JU','JA','','','','');
    $string = str_replace($rus,$lat,$string);
    $string = strtr($string,
    "АБВГДЕЗИЙКЛМНОПРСТУФХЫЭабвгдезийклмнопрстуфхыэ",
    "ABVGDEZIJKLMNOPRSTUFHIEabvgdezijklmnoprstufhie");
    return $string;
    }

    Поиск по запросу.

    Первым делом разбиваем запрос на слова в массив $words, выделив для русских слов корень стеммером.

    Формируем поисковый запрос так.

    for($i=0;$i<$num;$i++)
    {
    $if_clause.="iw.word='".$words[$i]."'";
    if($i!=$num-1) $if_clause.=" or ";
    }
    $query="select il.id,il.url,il.title,il.short, count(distinct iw.id)*1000 + sum(ii.times) as rel
    from indexing_link il, indexing_index ii, indexing_word iw
    where (".$if_clause.") and ii.word=iw.id and il.id=ii.link
    group by il.id order by rel desc";

    Ссылки по теме

    Русский стеммер с улучшеными характеристиками, от разработчика поиска на Рамблере:
    http://linguist.nm.ru/stemka/stemka.html

    Функция языка PHP для вычисления расстояния между строками:
    http://www.php.net/manual/en/function.levenshtein.php

    Яндекс.XML — это сервис, позволяющий делать автоматические поисковые запросы к Яндексу и публиковать его ответы у себя на сайте в собственном дизайне.
    http://xml.yandex.ru/

    Яndex.Server — приложение для полнотекстового поиска информации на вашем веб-сервере или в локальной сети с учетом морфологии русского языка.
    http://company.yandex.ru/technology/products/yandex-server.xml

    Медленный, но интересный корректор правописания:
    http://norvig.com/spell-correct.html

    http://sphinxsearch.com
    Бесплатный поисковый механизм. Требует компиляции и установки на сервер.
    Содержит API для интеграции с PHP, Python, Perl, и Ruby.
    Из особенностей:

    - быстрая работа (10 MB/сек индексация, запрос 0.1 сек на 2 Гб базе)
    - масштабируемость, распределенный поиск
    - русский и английский стемминг
    - ПХП-модуль не требует компиляции для работы

    http://www.dataparksearch.org
    Поисковый механизм с открытым кодом. Фронт-енд в виде CGI приложения. Поддерживает:
    - словари словоформ ISpell
    - синонимы для русского и английского языков
    - логический язык запросов (boolean)
    - исправление правописания на основе словарей Aspell

    P.S. Данная статья писалась с надеждой на то, что в большем числе сайтов будет организован удобный и полезный поиск. Ведь со временем количество информации в сети растёт, и одной из приоритетных задач разработчиков я считаю обеспечение эффективного её поиска.

    http://alexblack.habrahabr.ru/




    Рубрика: PHP




    Вышел MySQL 5.1.30, первый стабильный рели....

    MySQL

    После публикации 29 тестовых версий анонсирован первый стабильный релиз MySQL 5.1, пригодный для промышленной эксплуатации и обеспечивающий увеличение производительности для "тяжелых" SQL запросов, по сравнению с MySQL 5.0, примерно на 15-20%. Главные новшества появившиеся в MySQL 5.1:


    Подробнее... | Рубрика: MySQL | Добавлено: 28.11.2008

    Тестирование параллельных программ.

    Тестирование

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


    Подробнее... | Рубрика: Тестирование | Добавлено: 28.11.2008

    Архитектура AMD64 (EM64T).

    Архитектура AMD

    Аннотация. В статье кратко рассматривается архитектура AMD64 компании AMD и ее реализация EM64T компании Intel. Описаны особенности архитектуры, ее возможности, достоинства и недостатки.


    Подробнее... | Рубрика: Архитектура AMD | Добавлено: 27.11.2008

    Остальные статьи:

    Платформа 2009. Определяя будущее
    Windows Vista Bridge Sample Library - упра...
    Оптимизация 64-битных программ
    Подгрузка через AJAX HTML-кода, содержащег...
    Обзор нового релиза самой мощной Ajax библ...
    Firebug 1.3 и 1.4 alpha — что нового и инт...
    Релиз Microsoft Silverlight 2.0. Что новог...
    XML документация в C#
    Курсоры в MySQL 5
    Microsoft опубликовала подробности о сесси...
    Microsoft делится подробностями о том, что...
    Тестируем новый javascript от нового брауз...
    MySQL Query Cache
    Использование провайдеров компиляции в As...
    Чего мы ждем от C# 4.0
    Delphi 2009 и C++Builder 2009
    Джоэл Спольски и Джеф Этвуд запустили новы...
    Поиск кода Google /* что нового? */
    10 jQuery скриптов для улучшения интерфейс...
    Генераторы отчетов FastReport 4 и QuickRep...


    Цитата дня (все,добавить):

    Портал фрилансеров

    работа на дому


        Рубрикатор

    Программирование

    C/С++
    Обучение
    Windows API
    XAML
    Моделирование
    Паттерны
    Visual Basic 7 .NET
    WxWidgets
    Функции WinApi
    Функции С++
    Разработка под Mac OS
    Eiffel
    Visual Studio 2008
    UI дизайн
    Алгоритмы
    Конкурсные статьи
    Turbo Pascal
    Visual Studio
    CASE-средства
    Visual Studio 2005
    Без VCL
    Delphi
    Тех. документация
    Тестирование
    Software Testing
    ООП
    TCP/IP
    Google Android
    Windows Installer
    .NET Framework
    Драйвера
    C# C Sharp
    Справка
    Проектирование
    Информ. системы
    Visual Basic
    Assembler
    Оптимизация кода
    Gtk+
    Компоненты
    Реинжиниринг
    Управление проектами
    Extreeme programming
    Lotus Notes
    Алгебраическое проектирование


    Интернет технологии

    PHP
    Perl
    ASP
    WAP
    Cookies
    SSI
    CGI
    Web Servers
    VB Script
    DNS
    CSS
    XML
    Html
    Java Script
    Java2ME
    Firewall
    Flash
    .htaccess
    Apache
    VRML
    Протоколы
    Поисковые системы
    Технология JAVA
    Учебник по PHP
    Учебник по JavaScript
    Учебник по XML
    Java Q&A
    AJAX
    DHTML
    XHTML
    Dreamweaver
    Web 2.0
    Python
    Вебмастеру
    Cisco
    Ruby on Rails
    Silverlight

    Базы данных

    Access
    InterBase
    MySQL
    Oracle
    ADO .NET
    Основы SQL
    Учебник по Access 2002
    MS
    Microsoft FoxPro
    Доступ к данным
    XML в MS SQL Server 2000
    ODBC и MyODBC
    Обучение
    Caché
    DB2
    PostgresSQL
    Sybase
    Теория
    Хранилища данных
    Безопасность
    Реляционные данные
    MySQL и mSQL

    Остальное:

    Разное
    Обзоры книг
    Безопасность
    Графика и дизайн
    Юмор
    Linux
    Фракталы
    Microsoft Axapta
    Многоядерность
    Сети
    Microsoft Office
    Работа
    MS-DOS
    Криптография
    Графика и игроделание
    Новости SDK
    Системы защиты
    Учебник по AutoCad
    CVS
    Windows XP
    Windows Server 2003
    Windows Vista
    Windows 7
    Мероприятия