Основы PHP
  Что такое PHP?
  Возможности PHP
  Преимущества PHP
  История развития
  Что нового в PHP5?
  «Движок» PHP
  Переход на PHP 5.3
New Переход на PHP 5.6
  Введение в PHP
  Изучение PHP
  Основы CGI
  Синтаксис PHP
  Типы данных PHP
  Переменные в PHP
  Константы PHP
  Выражения PHP
  Операторы PHP
  Конструкции PHP
  Ссылки в PHP
  PHP и ООП
  Безопасность
  Функции PHP
  Функции по категориям
  Функции по алфавиту
  Стандартные функции
  Пользовательские
  PHP и HTTP
  Работа с формами
  PHP и Upload
  PHP и Cookies
  PHP и базы данных
  PHP и MySQL
  Документация MySQL
  Учебники
  Учебники по PHP
  Учебники по MySQL
  Другие учебники
  Уроки PHP
  Введение
  Самые основы
  Управление
  Функции
  Документация
  Математика
  Файлы
  Основы SQL
  Дата и время
  CURL
  Изображения
  Стили
  Безопасность
  Установка
  Проектирование БД
  Регулярные выражения
  Подготовка к работе
  Быстрый старт
  Установка PHP
  Установка MySQL
  Конфигурация PHP
  Download / Скачать
  Скачать Apache
  Скачать PHP
  Скачать PECL
  Скачать PEAR
  Скачать MySQL
  Редакторы PHP
  Полезные утилиты
  Документация
  PHP скрипты
  Скачать скрипты
  Инструменты
  PHP в примерах
  Новости портала
 Главная   »  Сборник статей
 
 

Поисковый механизм на PHP-MySQL

Итак, у вас полностью динамический сайт, на котором находится большое количество различных данных (любого вида – форумы, статьи и т.п.). Преимущественно большие данные хранятся в BLOBах (чего и вам наверное не удалось избежать), следовательно невозможно сделать ничего полезного, используя стандартный вид запроса LIKE %searchword% так как вывод не будет соответствующим (то есть релевантным).

Должен быть другой путь. И он есть :-).

Шаг один: Редукция "посторонних" слов из blob'а

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

Итак, мы сейчас пытаемся сделать – выбрать из данных эти слава, и, - в ново созданной табличке с двумя полями: словом и его указателем (счетчиком). Нам необходимо что-то вроде такого: 

+-----+---------------+ 
| qid | word          | 
+-----+---------------+ 
| 6   | links         | 
| 5   | Fire          | 
| 5   | topics        | 
| 5   | related       | 
| 5   | Shakespeare   | 
| 4   | people        | 
| 4   | Knowpost      | 
| 3   | cuba          | 
| 3   | cigar         | 
+-----+---------------+ 


Так, давайте создадим собственно табличку:

CREATE TABLE search_table( 
word VARCHAR(50), 
qid INT) 


Следующим шагом будет – обработать и переместить данные в нашу таблицу search_table. 

<?php 
$query = "SELECT blob,identifier FROM your_table"; 
$result = mysql_query($query); 
$number = mysql_numrows($result); 
$j = 0; 
WHILE ($j < $number) { 

/* Наш "blob" */ 
$body = mysql_result($result,$j,"blob"); 

/* Наш "identifier */ 
$qid = mysql_result($result,$j,"qid"); 

/* Открыть файл с посторонними словами в массив */ 

$noise_words = file("noisewords.txt"); 
$filtered = $body; 

/* Помещаем пробел перед первым словом */ 
$filtered = ereg_replace("^"," ",$filtered); 

/* Теперь мы избавились от ненужных слов и
можем поместить то, что осталось – в массив
*/ 

/* Пробегаем циклом и удаляем неправильные слова */ 

for ($i=0; $i < count($noise_words); $i++) { 
$filterword = trim($noise_words[$i]); 
$filtered = 
eregi_replace(" $filterword "," ",$filtered); 


$filtered = trim($filtered); 
$filtered = addslashes($filtered); 
$querywords = ereg_replace(",","",$filtered); 
$querywords = ereg_replace(" ",",",$querywords); 
$querywords = ereg_replace("\?","",$querywords); 
$querywords = ereg_replace("\(","",$querywords); 
$querywords = ereg_replace("\)","",$querywords); 
$querywords = ereg_replace("\.","",$querywords); 
$querywords = ereg_replace(",","','",$querywords); 
$querywords = ereg_replace("^","'",$querywords); 
$querywords = ereg_replace("$","'",$querywords); 

/* Теперь мы должны иметь что-то типа
'Word1','Word2','Word3' 
так что теперь мы можем загнать все в массив
*/ 

$eachword = explode(",", $querywords); 

/* наконец-то мы можем пробежаться по
массиву и поместить каждое слово в базу данных,
вместе со счетчиком
*/ 


for ($k=0; $k < count($eachword); $k++) { 
$inputword = "INSERT INTO search_table 
VALUES($eachword[$k],$qid)"; 
mysql_query($inputword); 


/* Пробежаться по циклу еще разок с новыми данными */ 
$j++; 


?> 

Этот скрипт обрабатывает ваши старые данные. Необходимо добавить подобную же обработку на добавление данных в вашу базу данных (когда её вводит пользователь, хозяин – или кто угодно) – так, чтобы база обновлялась в процессе. 

Шаг два: Поиск в таблице

Теперь мы имеем таблицу с ключевыми словами и счетчиками. Как собрать запрос?
Во-первых, необходимо переформатировать (нет, не жесткий диск) – слова поиска в строку вида 'word1','word2','word3' и записать её в $querywords. 
Далее использовать подобный ниже следующему запрос:

SELECT count(search_table.word) as score, search_table.qid,your_table.blob 
FROM search_table,your_table 
WHERE your_table.qid = search_table.qid AND search_table.word 
IN($querywords) 
GROUP BY search_table.qid 
ORDER BY score DESC"; 


Вывод же может быть, например, таким:

<?php 

$getresults = mysql_query($search); 
$resultsnumber = mysql_numrows($getresults); 

IF ($resultsnumber == 0) { 

PRINT "Ничего не найдено. "
."Попробуйте использовать другие ключевые слова."; 

} ELSEIF ($resultsnumber > 0) { 

PRINT "Поиск вернул $resultsnumber результатов<BR>"
     ."Расположение по релевантности &lt;BR>&lt;BR>"; 
for($count = 0; $count < $resultsnumber; $count++) { 
$body = mysql_result($getresults,$count,"blob"); 
$qid = mysql_result($getresults,$count,"qid"); 

$body2print = substr($body, 0, 100); 
$cnote = $count+1; 
PRINT "$cnote. <a href=yourcontent.php3?qid=$qid> "
     ."<i>$body2print...</i></a><BR>"; 



?> 

Итак, у вас есть механизм поиска по ключевым словам в вашей базе данных по релевантности (актуальности запросу).
Конечно, это не Yandex и не Google :-))).
Но у нас теперь есть небольшой поисковый механизм, который вполне быстро и грамотно работает и вполне подходит обычному пользователю (который не собирается использовать логические элементы и т.п.).


Вот лист моих "посторонних" слов:

noisewords.txt 
-------------- 

about 
after 
ago 
all 
almost 
along 
also 
am 
an 
and 
answer 
any 
anybody 
anywhere 
are 
aren't 
around 
as 
ask 
at 
bad 
be 
been 
before 
being 
best 
better 
between 
big 
but 
by 
can 
can't 
come 
could 
couldn't 
day 
did 
didn't 
do 
does 
don't 
down 
each 
either 
else 
even 
ever 
every 
everybody 
everyone 
far 
find 
for 
found 
from 
get 
go 
going 
gone 
good 
got 
had 
has 
have 
haven't 
having 
her 
here 
hers 
him 
his 
home 
how 
href 

if 
in 
into 
is 
isn't 
it 
its 
know 
large 
less 
like 
little 
looking 
look 
many 
me 
more 
most 
must 
my 
near 
never 
new 
news 
no 
none 
not 
nothing 
of 
off 
often 
old 
on 
once 
only 
or 
other 
our 
ours 
out 
over 
page 
please 
question 
rather 
recent 
she 
should 
sites 
small 
so 
some 
something 
sometime 
somewhere 
than 
true 
thank 
that 
the 
their 
theirs 
them 
then 
there 
these 
they 
this 
those 
though 
through 
thus 
time 
times 
to 
too 
under 
until 
untrue 
up 
upon 
use 
users 
version 
very 
via 
want 
was 
way 
web 
were 
what 
when 
where 
which 
who 
whom 
whose 
why 
wide 
will 
with 
within 
without 
world 
worse 
worst 
would 
www 
yes 
yet 
you 
your 
yours

 
 » Обсудить эту статью на форуме

 
 Сборник статей 
 Содержание раздела 
Есть еще вопросы или что-то непонятно - добро пожаловать на наш  форум портала PHP.SU 
 

 
Powered by PHP  Powered By MySQL  Powered by Nginx  Valid CSS