Полнотекстовый поиск в MySQL

Аватара пользователя
Assasin
Сообщения: 103
Зарегистрирован: 17 фев 2011
В общем я пишу что то на подобии сервиса "Возможно вы искали", ну в гугле или яше есть такая..
мне чтобы не исправлять пользователя по шаблону, т.е например человек написал "Скачать филм" не искать по точному совпадению, это было бы глупо, ибо все предложения все равно не предугадаешь..я и решил разбивать строку на слова и уже из базы конкретные слова в предложение изменять..
все шло хорошо пока я не добрался до этапа когда нужно заменить сразу два слова..и тут то самое смешное и произошло))
я тупо не знаю как получит второе слово из переменной $errortext['wrongtext'], может вы подскажете? вот если не лень конечно(могу отблагодарить)

вот код

Код: Выделить всё

$broken = explode(" ",$ask);
$part = $broken['0'];
$part1 = $broken['1'];
$part2 = $broken['2'];
$part3 = $broken['3'];
$part4 = $broken['4'];
$part5 = $broken['5'];
echo $part,' ';
echo $part1,'<br>';
$words = mysql_query("SELECT * FROM errortext WHERE MATCH (textwrong) AGAINST ('$part,$part1')",$sql);
$wordcount = mysql_num_rows($words);
while(
$wor = mysql_fetch_array($words))
{
    if($wordcount == 1 && $wor['textwrong'] == $part)
    {
        $wordlink = preg_replace("/\s/","+",$wor['words']);
        $partlink = $wor['words']."+".$part1;
        printf("<font class='wrongtext'>Возможно вы ищете</font> <a href=search.htm?&str=1&i=%s class='wrongtext'>%s %s</a><br>",$partlink,$wor['words'],$part1);
    }
    elseif($wordcount == 1 && $wor['textwrong'] == $part1)
    {
        $wordlink = preg_replace("/\s/","+",$wor['words']);
        $partlink = part."+".$wor['words'];
        printf("<font class='wrongtext'>Возможно вы ищете</font> <a href=search.htm?&str=1&i=%s class='wrongtext'>%s %s</a><br>",$partlink,$part,$wor['words']);
    }
    elseif($wordcount == 2 && $wor['textwrong'] == $part1)
    {
        $words2 = mysql_query("SELECT * FROM errortext WHERE MATCH (textwrong) AGAINST ('$part,$part1')",$sql);
        while($wor = mysql_fetch_array($words))
        {
            $wordlink = preg_replace("/\s/","+",$wor['words']);
            $partlink = part."+".$wor['words'];
            printf("<font class='wrongtext'>Возможно вы ищете</font> <a href=search.htm?&str=1&i=%s class='wrongtext'>%s %s</a><br>",$partlink,$part,$wor['words']);
        }
    }
    else
    
{
    }
}

Аватара пользователя
Distructor
Администратор
Сообщения: 1599
Зарегистрирован: 28 дек 2009
примерно так:

Код: Выделить всё

$broken = explode(" ",$ask);
$parts = implode(',', $broken);

$bad_words = array();
$words = mysql_query("SELECT * FROM errortext WHERE MATCH (textwrong) AGAINST ('$parts')",$sql);
$wordcount = mysql_num_rows($words);
while(
$wor = mysql_fetch_array($words))
{
    $bad_words[ $wor['textwrong'] ] = $wor['words'];
}
$ask_replaced = strtr($ask, $bad_words);
$ask_replaced_link = urlencode($ask_replaced);

if ($ask != $ask_replaced)
    echo "<font class='wrongtext'>Возможно вы ищете</font> <a href='search.htm?&str=1&i=$ask_replaced_link' class='wrongtext'>$ask_replaced</a><br>";


но тебе надо учеть все разделители а не только пробел

Аватара пользователя
Assasin
Сообщения: 103
Зарегистрирован: 17 фев 2011
Спасибо огромное это то что надо! И форум просто отличный)

Аватара пользователя
Distructor
Администратор
Сообщения: 1599
Зарегистрирован: 28 дек 2009
да и еще один момент. правильнее будет

Код: Выделить всё

$parts mysql_real_escape_string(implode(','$broken)); 

введенному пользователем никогда нельзя доверять, потому перед использование полученных данных в запросе не забывай их обрабатывать для защиты от sql-инъекций.

Аватара пользователя
Assasin
Сообщения: 103
Зарегистрирован: 17 фев 2011
Функция не работает.заменить предлагает,но на неправильный вариант.
это внешний файл(подключение к базе есть)

Код: Выделить всё

function wrongReplace ($ask) {
   $broken = explode(" ",$ask);
   $parts = mysql_real_escape_string(implode(',', $broken));
   $bad_words = array();
   $words = mysql_query("SELECT * FROM errortext WHERE MATCH (textwrong) AGAINST ('$parts' ",$sql);
   $wordcount = mysql_num_rows($words);
   while($wor = mysql_fetch_array($words))
       $bad_words[ $wor['textwrong'] ] = $wor['words'];
   return strtr($ask, $bad_words);
}

это тот в котором должно показываться

Код: Выделить всё

$ask_replaced = wrongReplace ($ask);
$ask_replaced_link = urlencode($ask_replaced);

if ($ask != $ask_replaced)
    echo "<font class='wrongtext'>Возможно вы ищете</font> <a href='search.htm?&str=1&i=$ask_replaced_link' class='wrongtext'>$ask_replaced</a><br>";

Подскажи пожалуйста что не так?

Аватара пользователя
Distructor
Администратор
Сообщения: 1599
Зарегистрирован: 28 дек 2009
Assasin писал(а):Функция не работает
текст ошибки приведи.

кстати на заметку http://api.yandex.ru/speller/doc/dg/ref ... ckText.xml можно реализовать проверку средствами js по словарю яндекса)

Аватара пользователя
Assasin
Сообщения: 103
Зарегистрирован: 17 фев 2011
братан,яша не катит)
есть база аналогичная сервису яше по исправлению слов..но когда данная программа заключена в функцию то она берет из базы неправильно слово и заменяет его на тоже неправильное,а не на правильное..
в общем что то не передается..
пробывал

Код: Выделить всё

GLOBAL $bad_words;
GLOBAL $ask;

не помогает((
скрин сюда как можно выложить?

Аватара пользователя
Distructor
Администратор
Сообщения: 1599
Зарегистрирован: 28 дек 2009
ну вставь перед

Код: Выделить всё

 $ask_replaced = wrongReplace ($ask);
отладочный вывод

Код: Выделить всё

var_dump($ask);


и посмотри что есть в переменной до передачи ее функции

Аватара пользователя
Assasin
Сообщения: 103
Зарегистрирован: 17 фев 2011

Код: Выделить всё

string(17) "dконтакте"

мне это не о чем не говорит)
на всякий случай сделал глобальной и $ask_replaced но это тоже не помогло..
я сделал проверку свою а твою убрал может поэтому,просто твоя почему то не реагирует

Код: Выделить всё

$brok = explode(" ",$ask);
$part = $brok['0'];
$part1 = $brok['1'];
$part2 = $brok['2'];
$part3 = $brok['3'];
$part4 = $brok['4'];
$part5 = $brok['5'];
$words = mysql_query("SELECT * FROM errortext WHERE MATCH (textwrong) AGAINST ('$part,$part1,$part3,$part4,$part5')",$sql);
$wordcount = mysql_num_rows($words);
while($wor = mysql_fetch_array($words))
{
$words_bad = $wor['textwrong'];
}
if(sizeof($words_bad) == 0)
{
}
elseif($wordcount > 0 || $brok['0'] == $words_bad || $brok['1'] == $words_bad || $brok['2'] == $words_bad || $brok['3'] == $words_bad)
{
var_dump($ask);
$ask_replaced = wrongReplace ($ask);
$ask_replaced_link = urlencode($ask_replaced);

    echo "<font class='wrongtext'>Возможно вы ищете</font> <a href='search.htm?&str=1&i=$ask_replaced_link' class='wrongtext'>$ask_replaced</a><br>";
}

это в файле где всё выводится

Код: Выделить всё

function wrongReplace ($ask) {
GLOBAL $bad_words;
GLOBAL $ask;
GLOBAL $ask_replaced;
   $broken = explode(" ",$ask);
   $parts = mysql_real_escape_string(implode(',', $broken));
   $bad_words = array();
   $words = mysql_query("SELECT * FROM errortext WHERE MATCH (textwrong) AGAINST ('$parts')",$sql);
   $wordcount = mysql_num_rows($words);
   while($wor = mysql_fetch_array($words))
   $bad_words[ $wor['textwrong'] ] = $wor['words'];
   return strtr($ask, $bad_words,$ask_replaced);
}

а это то что в подключенном файле..если есть время и не лень проведи глазами может что не так действительно

Аватара пользователя
Distructor
Администратор
Сообщения: 1599
Зарегистрирован: 28 дек 2009
глобальность у переменных тут не нужна

я сделал проверку свою а твою убрал может поэтому
то что ты сделал мягко говоря излишне - ты ищешь неправильные слова, считаешь число ошибок, и если ошибки есть еще раз запускаешь проверку, хотя уже мог бы выдать результат

описанного ранее блока вполне достаточно

Код: Выделить всё

// проверяем на ошибки
$ask_replaced = wrongReplace ($ask);
$ask_replaced_link = urlencode($ask_replaced);

// если были найдены ошибки
if ($ask != $ask_replaced)
    echo "<font class='wrongtext'>Возможно вы ищете</font> <a href='search.htm?&str=1&i=$ask_replaced_link' class='wrongtext'>$ask_replaced</a><br>";
else
    echo 'ошибок нет';


Assasin писал(а):string(17) "dконтакте"

"dконтакте" есть в твоей таблице описок? скорее всего нет, а вот "d контакте" по идее должен обработаться нормально

Аватара пользователя
Assasin
Сообщения: 103
Зарегистрирован: 17 фев 2011
не,есть dконтакте => вконтакте
ну в общем ладно это того не стоит в принципе..
сделал без функции и всё отлично)
я видишь почему так на функцию налегаю,просто я на хостинг выкладывать всё дело собираюсь и если я обрабатываю всю страницу обфускатором то ничего не работает а если подключаю файл предварительно уже обработанный им то всё ништяк))
может посоветуешь как защитить кроме зенда и обфускаторов исходный код?

Аватара пользователя
AgentSIB
Администратор
Сообщения: 328
Зарегистрирован: 17 май 2010
Вопрос. А зачем тебе нужно прятать код? Для демо версии можно разместить на своем компе. Или ты не доверяешь хостеру?
Frustra fit per plura quod potest fieri per pauciora © Закон "Бритвы Оккама"

Аватара пользователя
Assasin
Сообщения: 103
Зарегистрирован: 17 фев 2011
У меня с прошлым хостером сложная ситуация произошла. короче мой сайт оплату принимает через SMS замок.лог и пасс у меня там были название домена и пароль от бд..ну так эти суки взломали видимо тупым перебором мой аккаунт.после этого я думаю от хостинга можно всё ожидать.
вдруг кто то решит из сис.админов такое же как у меня сделать а тут на все готовенькое тока логотип поменяй..а мне лишняя конкуренция не нужна)я хоть криво пишу(начинающий) но идеи у меня оригинальные я их не для других писал.
кстати этот хостер ihc.ru
для поисковика)
отзывы о интернет хостинг центр , отзывы о ihc , отзывы о ihc.ru

Аватара пользователя
Distructor
Администратор
Сообщения: 1599
Зарегистрирован: 28 дек 2009
Для надожности надо использовать проверенные хостинги (например nic.ru или hc.ru),
а с хостингами за 1-50 рублей никогда никаких гарантий не будет.

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

Аватара пользователя
Assasin
Сообщения: 103
Зарегистрирован: 17 фев 2011
насчет hc.ru тоже много жалуются..
да уже сделал без функции хотя странно конечно.


Вернуться в «Вопросы по программированию»