Собственное поисковое ядро (часть 2.)

Скачать Собственное поисковое ядро (часть 2.)
Сейчас ищут:

GE_Pass

Житель
Регистрация
30.01.14
Сообщения
215
Реакции
48
Пишем собственное поисковое ядро. Часть 2.

Первая часть урока

1. Форма поиска и передаваемые данные

Небольшое отступление сделаем и посмотрим на нашу форму отправки данных:
Код:
<form action="search_result.php" method="post">
    <p><input id="search_input" name="search_word" type="text"><input id="search_button" type="submit"></p>
</form>

Как видите тут ничего необычного нет. Мы передаем значение search_word файлу search_result.php. Т.е. у нас в нашей системе добавился файл куда и будут выводиться результаты поиска и теперь наша структура выглядит вот так:

directory2.jpg


Т.е. в файле search_result.php мы будем получать значение запроса и обрабатывать его примерно таким образом:
Код:
if(isset($_REQUEST["search_word"])) {
    $query = trim($_REQUEST["search_word"]); //делаем небольшую чистку, можете добавить еще защиту от различных инъекций и подозрительных переменных, которые могут ввести вам вредные пользователи
    $keywords = explodeQuery($query); //тут наша функция с первой части урока
  
    $sql = "SELECT id, title, keywords, text, category FROM materials WHERE public=1"; //ищем только опубликованные материалы
    $result = mysql_query($sql);
    if ($mysql_num_rows($result)!=0) { //проверяем наличие записей, если нет, то естественно ничего не выведем и прекратим любую работу системы
        while($row = mysql_fetch_assoc($result))
        {
            $materials[$row[id]] = $row; //Формируем массив $materials с найденными материалами
        }
        echo searchResult($materials,$keywords); //выводим наш результат поиска, функцию мы рассмотрим ниже
    }
    else {
        echo "напишем тут какую-нибудь ошибку для пользователя";
    }
}

ак видите ничего сложного тут нет. У нас как видите появилась одна необъявленная функция searchResult(). Ее написанием сейчас мы и займемся.

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

Рассмотрим немного схему того, как система будет искать необходимые пользователю материалы:

shema.jpg


Составитель схем из меня никудышный, но думаю смысл понятен. Поэтому приступим к написанию функции.

Код:
function searchResult($materials, $keywords) {
    foreach ($materials as $material) { //Выше мы сформировали массив $materials который мы теперь выводим разбивая на элементы массива $material
        $title = htmlspecialchars(strip_tags($material[title]));    //Тут мы чистим все значения массива - title, text и keywords от тегов и посторонних символов
        $text = htmlspecialchars(strip_tags($material[text]));        //как вариант можно еще все слова перевести в нижний регистр
        $key = htmlspecialchars(strip_tags($material[keywords]));
        $wordWeight =0; //вес слова запроса приравниваем к 0
        foreach ($keywords as $word) {     //теперь для каждого поискового слова из запроса ищем совпадения в тексте
            $reg = "/(".$word.")/";     //маска поиска для регулярной функции
            /*   
                Автоматически наращиваем вес слова для каждого элемента массива.
                Так же сюда можно включить например поле description если оно у вас есть.
                Оставляем переменную $out, которая выводит значение поиска. Она нам может и не пригодится, но пусть будет, может быть вы найдете ей применение.
            */
            $wordWeight = preg_match_all($reg, $title, $out);    //как вариант можно еще для слов в заголовке вес увеличивать в два раза
            $wordWeight += preg_match_all($reg, $text, $out);    //но это вам понадобиться если вы будете выводить материалы в порядке убывания по релевантности
            $wordWeight += preg_match_all($reg, $key, $out);    //мы же пока этого делать не будем
            $material[relevation] += $wordWeight; //увеличиваем вес всего материала на вес поискового слова
          
            //раскрашиваем найденные слова функцией, которую мы писали в первой части урока
            $title = colorSearchWord($word, $title, "violet");
            $text = colorSearchWord($word, $text, "violet");
            $key = colorSearchWord($word, $key, "violet"); //незнаю зачем ключевые слова окрасил, их ведь не обязательно выводить пользователю :)
        }
        //Теперь ищем те материалы, у которых временный атрибут relevation не равен 0
        if($material[relevation]!=0) {
            //Возвращаем массивы в нормальное состояние с уже обработанными данными
            $material[title] = $title;
            $material[text] = $text;
            $material[keywords] = $key;
            echo simpleToTemplate($material, "search_result"); //новая функция, которая вернет нам шаблон с результатами поиска
        }
        //Иначе просто грохаем весь элемент material за ненадобностью
        else {
            unset($material);
        }
    }
}

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

3. Шаблон и функция его вызова.

Ну вот собственно мы подходим к функции визуального формирования результата запроса на основании шаблона search_result.tpl. Для начала рассмотрим функцию, которая при помощи буфера позволит нам динамически сформировать всю структуру HTML.

Код:
function simpleToTemplate($value, $template) {
        ob_start(); // Включаем буферизацию вывода, чтобы шаблон не вывелся в месте вызова функции
        // Подключаем необходимый нам шаблон, который просто ждет наш массив
        include('templates/'.$template.'.tpl');
        return ob_get_clean(); //Возвращаем результат буфера и очищаем его
    }

ункция достаточно небольшая, она передает нашему шаблону массив данных и материала, а тот в свою очередь собирает нам вменяемую HTML верстку, которую мы определим в самом шаблоне result_search.tpl.

Код:
<div id="search_result_element<? echo $value[id] ?>">
    <h4><a href='index.php?cat=<?=$value[category] ?>&amp;mat=<?=$value[id] ?>&amp;style=1'><?=$value[title] ?></a></h4>
    <? $text = "<p>".substr($value[text],0, 430)."</span>...</p>"; echo $text; ?>
    <p>Количество совпадений: <?=$value[relevation];?></p>

Вот собственно и готов поиск. В следующих уроках мы подумаем как улучшить наше ядро, рассмотрим новые приемы работы с массивами и улучшим в целом всю систему. Пример работы поиска можно посмотреть например на сайте www.protege-star.com

Спасибо за внимание.
 
А как реализовать это для OpenCart?
 
Назад
Сверху Снизу