Digs - Персональная территория

Авторский проект Артема Глазкова
? 
        Версия для печати (цвет)  

Использование материалов
Заметка #5
06 мая 2005

Организация поиска


    Организация индексного файла по сайту дает ряд преимуществ по сравнению с обычным поиском. Структура разделов сайта может быть различной. В частности, есть страницы, которые не лежат в виде отдельно файла, а составляются в зависимости от условий, причем результирующую страницу может дать только скрипт, ее генерирующий. Даже если мы напишем скрипт поиска с учетом особенностей каждого раздела (что уже сложно), то добавление на сайт еще одного раздела добавит нам еще хлопот. И даже если попробовать написать для каждого раздела свою подфункцию поиска, то при расширении функциональности поиска придется переписать все такие функции.
    Второй момент состоит в количестве файлов, которые нужно проверить. Дополнительное обращение к диску уменьшает скорость поиска. Также может быть снижена надежность поискового механизма при непредвиденных изменениях на сайте.
    
    Индексный файл
    Под индексным файлом я понимаю файл с некоторой структурой, которая хранит не только некий контент, в котором будет производиться поиск, но также управляющие элементы, позволяющие предоставить пользователю корректный результат запроса.
    Как уже было сказано, структура должна зависеть от предоставляемых пользователю результатов. Каждая строка результата поиска по моему сайту предстает в двух видах: либо это заголовок с пиктограммой, которая отличается для различных разделов, либо это заголовок плюс строка в которой было найдено слово. Во втором случае также своя пиктограмма. Вдобавок ко всему есть заголовок раздела.
    Индексный файл будет текстовый. Чтобы различать управляющие элементы первый символ каждой строки будет особым. В итоге получаем такую таблицу:

    # - заголовок раздела
    D - заголовок документа (статьи, раздела и т.д.)
    > - строка документа
    + - ссылка на изображение пиктограммы
    = - URL

    Организация в таком файле становится очень простой. При правильном составлении не придется заботиться о правильности индексного файла, т.е. не придется заниматься дополнительными проверками.
    Цикл. Получаем строку, выделяем первый символ. Если это #, D, +или =, то просто заносим остаток строки в соответствующую переменную. Дальнейший анализ: если > или D, то производим в строке поиск, и если нашли то выдаем результат. Перед этим не забываем проверять, если сменился раздел, то выводим имя раздела.

    Осталось разобраться с генерацией индексного файла. Как было описано в статье "Весь сайт в index.php" все разделы подключаются к основному файлу, чтобы зарегистрировать себя в меню и прочее. Лучшим вариантом будет в каждом файле раздела сделать регистрацию функции, которая будет возвращать массив строк для индексного файла.
    Для уменьшения размера индексного файла и, соответственно, для увеличения скорости поиска выполняем следующие функции:
1. выбрасываем все HTML и vB теги.
2. отбрасываем начальные и конечные пробелы.
3. убираем пустые строки

    
    Пример

    Григорий Остер
    Нет приятнее занятья,
    Чем в носу поковыряться.
    Всем ужасно интересно,
    Что там спрятано внутри.
    А кому смотреть противно,
    Тот пускай и не глядит.
    Мы же в нос к нему не лезем,
    Пусть и он не пристает.


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

+images/oster.gif
=stih/stih.txt
DГригорий остер

    Далее Поиск по тексту не меняет пиктограмму и не меняет ссылку. Поэтому остается добавить только текст:

>Нет приятнее занятья,
>Чем в носу поковыряться.
>Всем ужасно интересно,
>Что там спрятано внутри.
>А кому смотреть противно,
>Тот пускай и не глядит.
>Мы же в нос к нему не лезем,
>Пусть и он не пристает.

    Скрипт
    Ну и в заключение текст скрипта, производящего простейший поиск. Искомое слово в переменной $s. Функция dlower переводит текст к нижнему регистру.

$s1 dlower($s);
$ind file("search.dat");
$searched false;
$newcont true;
foreach(
$ind as $line){
  
$line str_replace("\n","",$line);
  
$line str_replace("\r","",$line);
  if (
$line=="") continue;
  
$c $line{0};
  
$line substr($line,1,strlen($line)-1);
  if (
$c!=">"$newcont true;
  switch (
$c){
    case 
"#"$razdview false$razdname $line; break;
    case 
"+"$docimage $line; break;
    case 
"="$docurl $line; break;
    case 
"D"$docname $line;
    case 
">"
      if (!
$newcont) continue;          
      
//выбрасываем все ненужные символы
      
$l strtr(dlower($line),"!?.,[]()%<>=/\\\"'-+*\n\r",      
                               
"                         ");
      
//окоймляем исходную строку и подстроку пробелами
      //чтобы искать по словам, а не по частям
      
if (strstr(" ".$l." "," ".$s1." ") !== false){
        if (!
$razdview){
          echo 
"<h1>$razdname</h1>\n";
          
$razdview true;
        }
        echo 
"<div style=\"margin-left: 50px;\">";
        echo 
"<img src=\"$docimage\">";
        echo 
"<a href=\"$docurl\"><b><font size=2>$docname</font></b><br>";
        if (
$c==">") echo $line."<br>\n";

        echo 
"</a><br></div>";
        
$searched true;
        
$newcont false;
      }
  }

if (!
$searched){
  echo 
"<br><h1>Ничего не найдено</h1>\n";
}


© 2005-16, Powered By Digs (Написать письмо, vk)