Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Скриптовые языки программирования > PHP
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 19.02.2013, 21:05   #1
Mr_freeman
Форумчанин
 
Аватар для Mr_freeman
 
Регистрация: 17.01.2010
Сообщений: 277
По умолчанию Поиск по сайту (MySQL)

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

Пока остановился на на следующей мысли:
  • Берется поисковая фраза
  • Разбивается на слова, которые добавляются в массив
  • Идет поиск по необходимым полям в базе по каждому слову.
  • Результаты для каждого поля заносятся в массив (сколько слов из фразы присутствуют в конкретной записи - как бы "релевантность")
  • Результирующий массив сортируется по "релевантности"
  • Выводится результат

Как вам такой вариант?
Хотелось бы услышать ваши решения по этому вопросу.

Последний раз редактировалось Mr_freeman; 20.02.2013 в 10:31.
Mr_freeman вне форума Ответить с цитированием
Старый 20.02.2013, 10:19   #2
ADSoft
Старожил
 
Регистрация: 25.02.2007
Сообщений: 4,158
По умолчанию

да нормально .... можно еще добавить типа ВСЕ слова из фразы чтоб такие документы искал или ЛЮБЫЕ .....Хотя в релевантность попадут все....
.. для релевантности еще надо исключат мелкие слова .... типа союзов итд итп
ADSoft вне форума Ответить с цитированием
Старый 20.02.2013, 10:29   #3
Mr_freeman
Форумчанин
 
Аватар для Mr_freeman
 
Регистрация: 17.01.2010
Сообщений: 277
По умолчанию

А как должен задаваться массив для этого, чтобы хранить в каждом элементе количество совпадений и mysql_fetch_array()? (я кажется не работал еще с такими массивами из "записей")

Тобишь на яваскрипте это было бы что то типа
Код:
arr.push({count:3,bd:result});
Как в PHP с такими данными работают?
Mr_freeman вне форума Ответить с цитированием
Старый 20.02.2013, 10:30   #4
Mr_freeman
Форумчанин
 
Аватар для Mr_freeman
 
Регистрация: 17.01.2010
Сообщений: 277
По умолчанию

И еще вопрос: какой метод сортировки оптимальней использовать? Обычный пузырек подойдет?
Mr_freeman вне форума Ответить с цитированием
Старый 20.02.2013, 10:31   #5
ADSoft
Старожил
 
Регистрация: 25.02.2007
Сообщений: 4,158
По умолчанию

неясен вопрос...
если строку разбить в массив - explode()
ADSoft вне форума Ответить с цитированием
Старый 20.02.2013, 11:02   #6
Mr_freeman
Форумчанин
 
Аватар для Mr_freeman
 
Регистрация: 17.01.2010
Сообщений: 277
По умолчанию

Ну с первым я разобрался, а строку я разбил вот так
PHP код:
$keys=preg_split('/[^\w]+/',$phrase); 
Mr_freeman вне форума Ответить с цитированием
Старый 20.02.2013, 11:06   #7
ADSoft
Старожил
 
Регистрация: 25.02.2007
Сообщений: 4,158
По умолчанию

тогда в чем вопрос то
ADSoft вне форума Ответить с цитированием
Старый 20.02.2013, 11:11   #8
Mr_freeman
Форумчанин
 
Аватар для Mr_freeman
 
Регистрация: 17.01.2010
Сообщений: 277
По умолчанию

Цитата:
Сообщение от ADSoft Посмотреть сообщение
тогда в чем вопрос то
Пока все получается, спасибо. Я еще напишу, если какие то трудности возникнут.
Mr_freeman вне форума Ответить с цитированием
Старый 20.02.2013, 13:51   #9
Mr_freeman
Форумчанин
 
Аватар для Mr_freeman
 
Регистрация: 17.01.2010
Сообщений: 277
По умолчанию

Итак, класс готов. С ООП я только начинаю работать, по этому буду рад, если укажите на ошибки в структуре класса или в самом алгоритме. Пока поиск можно осуществлять только по одному столбцу одной таблицы, в которой должен быть уникальный индекс (пока по умолчанию столбец 'id').

Собственно ,код:
PHP код:
<?
//require a database connect
class Search{
    
//search phrase,result
    
public $phrase,$result;
    
//table and col of search
    
private $table,$col;
    
    
//init
    
function Search($phrase,$table,$col){
        
$this->phrase=$phrase;
        
$this->table=$table;
        
$this->col=$col;
    }
    
    
//backlight
    
private function backlight($res,$key){
        
$res[($this->col)]=preg_replace('/('.$key.')/i','<b style="background-color:#ffff00;">$1</b>',$res[($this->col)]);
        return 
$res;
    }
    
    
//sort
    
private function sort_assoc($arr){
        
$size sizeof($arr)-1;
        for (
$i $size$i>=0$i--) {
            for (
$j 0$j<=($i-1); $j++)
                if (
$arr[$j]['relevance']<$arr[$j+1]['relevance']){
                    
$k $arr[$j];
                    
$arr[$j] = $arr[$j+1];
                    
$arr[$j+1] = $k;
                }
        }
        return 
$arr;
    }
    
    
//start search
    
public function start(){
        
$keys=preg_split('/[^\wА-Яа-я]+/uis',$this->phrase);
        
//enumeration words of phrase
        
foreach ($keys as $t => $key){
            
//condition of word
            
if (mb_strlen($key,'UTF-8')>2){
                
$key=mysql_real_escape_string($key);
                
//query to database
                
$query='SELECT * FROM `'.($this->table).'` WHERE `'.($this->col).'` LIKE \'%'.$key.'%\'';
                
$result=mysql_query($query);
                
$rows=mysql_num_rows($result);
                if (
$rows!=0){
                    
//save result to array
                    
while($res=mysql_fetch_array($result)){
                        
//new result
                        
if ($this->result[$res['id']]==NULL){
                            
$res $this->backlight($res,$key);
                            
$this->result[$res['id']]=Array('data'=>$res,'relevance'=>1);
                        
//increase relevance
                        
}else{
                            
$this->result[$res['id']]['data']=$this->backlight($this->result[$res['id']]['data'],$key);
                            
$this->result[$res['id']]['relevance']++;
                        }
                    }
                }
            }
        }
        if (
sizeof($this->result)!=0){
            
//unset indexes
            
$index=0;
            foreach ((
$this->result) as $t => $value){
                
$temp[$index]=$value;
                
$index++;
            }
            
$this->result=$temp;
            
//sort
            
$this->result=$this->sort_assoc($this->result);
        }
    }
}
?>
Mr_freeman вне форума Ответить с цитированием
Старый 27.02.2013, 16:36   #10
demeros
Пользователь
 
Регистрация: 29.03.2010
Сообщений: 35
По умолчанию

Какая СуБД и тип таблиц используется?

Для MySQL MyIASM давно придумали full text search.
http://phpclub.ru/mysql/doc/fulltext-search.html

Также есть Apache Lucene, Яндекс.Сервер, Shpinx и много других которые намного лучше справляются с задачей поиска.
demeros вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
поиск по сайту subbota HTML и CSS 3 01.09.2011 19:34
Поиск по сайту! Марат05 HTML и CSS 4 20.12.2010 19:49
Поиск по сайту Linel PHP 2 15.06.2009 11:18
поиск по сайту ара PHP 4 07.04.2009 19:16