Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
C++. Мастер-класс в задачах и примерах. Авторы: Кузнецов М.В., Симдянов И.В. PHP. Практика создания Web-сайтов (второе издание). Авторы: Кузнецов М.В., Симдянов И.В. Социальная инженерия и социальные хакеры. Авторы: Кузнецов М.В., Симдянов И.В. Самоучитель MySQL 5. Авторы: Кузнецов М.В., Симдянов И.В. MySQL 5. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум MySQL

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Поиск по базе данных - что-нибудь получше оператора LIKE
 
 автор: (Sandr)   (20.03.2011 в 19:30)   письмо автору
 
 

Помогите с реализацией поиска по базе.
Вот запрос
$search = mysql_real_escape_string($_POST['search']);
$search = mysql_query("SELECT * FROM `text` WHERE `text` LIKE '%$search%'");
while($sql = mysql_fetch_array($search))
{
echo htmlspecialchars($sql['text']);
echo '<hr>';
}

в поле `text` есть 4 записи. В одну запись я скопировал биографию группы Ария, во второй и третей тексты на экономическую тематику, в четвёртой случайный набор букв и знаков вида > < ... Ввёл в поиск слово "Ария" вывело 3 первых статьи. Мне кажется, что такой поиск ищет не по словам или словосочетаниям, а вообще по последовательности букв введённых в поиске, даже по нечёткой, т.е. в моём случае скрипт производит поиск не по целому слову "Ария" а даже по "а", "ар", "ари", "ария", "Ар" и т.д, что мне не подходит((

  Ответить  
 
 автор: (Sandr)   (20.03.2011 в 19:34)   письмо автору
 
   для: (Sandr)   (20.03.2011 в 19:30)
 

Искал по форуму, но именно таких вопросов не нашёл

  Ответить  
 
 автор: cheops   (20.03.2011 в 19:37)   письмо автору
 
   для: (Sandr)   (20.03.2011 в 19:30)
 

Нет по "а", "ар", "ари" ваш запрос искать не будет, только по "ария", т.е. слово "сценария" будет ему удовлетворять.

Возможно вам больше подойдет поиск по регулярным выражениям RLIKE или полнотекстовый поиск MATCH ... AGAINST(), в которых можно указать границы слов - у баз данных обычно очень широкие поисковые возможности.

  Ответить  
 
 автор: (Sandr)   (20.03.2011 в 19:48)   письмо автору
 
   для: cheops   (20.03.2011 в 19:37)
 

MATCH ... AGAINST() читал, что он не очень быстрый.
RLIKE, можете предоставить немного инфы по нему или пример как делать в моём случае?

  Ответить  
 
 автор: cheops   (20.03.2011 в 20:09)   письмо автору
 
   для: (Sandr)   (20.03.2011 в 19:48)
 

>MATCH ... AGAINST() читал, что он не очень быстрый.
Зря вы так - очень шустрая штука... Там же индекс создается, т.е. посути вся таблица разбирается на части для ускорения и оптимизации поиска, поисковой машины.

>RLIKE, можете предоставить немного инфы по нему или пример как делать в моём случае?
Тоже самое, что и RLIKE, только уберите % и добавьте границы [[:<:]], [[:>:]]
SELECT * FROM `text` 
WHERE `text` RLIKE '[[:<:]]$search[[:>:]]'

  Ответить  
 
 автор: (Sandr)   (20.03.2011 в 20:29)   письмо автору
 
   для: cheops   (20.03.2011 в 20:09)
 

$search = mysql_query("SELECT * FROM `text` WHERE `text` RLIKE '[[:<:]]$search[[:>:]]'");
Выдаёт ошибку: Parse error: syntax error, unexpected '[', expecting T_STRING or T_VARIABLE or T_NUM_STRING in Z:\home\my-blog2.ru\www\2.php on line 6

  Ответить  
 
 автор: cheops   (20.03.2011 в 20:32)   письмо автору
 
   для: (Sandr)   (20.03.2011 в 20:29)
 

Ясно, исправьте следующим образом, чтобы PHP не думал, что квадратная скобка относится к элементу массива
<?php
  
...
  
$search mysql_query("SELECT * FROM `text` WHERE `text` RLIKE '[[:<:]]{$search}[[:>:]]'");
  ...
?>

  Ответить  
 
 автор: (Sandr)   (20.03.2011 в 20:32)   письмо автору
 
   для: cheops   (20.03.2011 в 20:09)
 

А индексы не хочу использовать, т.к. они увеличивают таблицу(

  Ответить  
 
 автор: cheops   (20.03.2011 в 20:35)   письмо автору
 
   для: (Sandr)   (20.03.2011 в 20:32)
 

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

  Ответить  
 
 автор: (Sandr)   (20.03.2011 в 20:39)   письмо автору
 
   для: cheops   (20.03.2011 в 20:35)
 

Хм.. Сейчас вообще ничего не выводит( Наверно придётся пробовать разбираться с индексами..

  Ответить  
 
 автор: cheops   (20.03.2011 в 20:41)   письмо автору
 
   для: (Sandr)   (20.03.2011 в 20:39)
 

А прямой запрос вида что-нибудь выводит?
SELECT * FROM `text` WHERE `text` RLIKE '[[:<:]]ария[[:>:]]'

  Ответить  
 
 автор: (Sandr)   (20.03.2011 в 20:54)   письмо автору
 
   для: cheops   (20.03.2011 в 20:41)
 

Тоже ничего. Это может быть из-за того, что я уже поставил индексы?

  Ответить  
 
 автор: (Sandr)   (20.03.2011 в 21:07)   письмо автору
 
   для: cheops   (20.03.2011 в 20:41)
 

Немного изменил таблицу и сам код, но по прежнему ничего не выводит

<?php
require_once $_SERVER['DOCUMENT_ROOT'].'/connect.php';
$search mysql_query("SELECT * FROM `article` WHERE MATCH (name,text,tags) AGAINST ('Aрия')");
while(
$sql mysql_fetch_array($search))
{
    echo 
htmlspecialchars($sql);
    echo 
'<hr>';
}
echo 
count($search);            // выводит 1
echo '<form action="2.php">
            Введите слова для поиска:<br>
            <input type="text" name="search"><br>
            <input type="submit" value="Отправить">
            </form>'
;
?>


CREATE TABLE `article` (
`id` int(15) NOT NULL auto_increment,
`id_cat` int(15) NOT NULL,
`name` varchar(50) NOT NULL,
`text` text NOT NULL,
`date` int(25) NOT NULL,
`tags` varchar(50) NOT NULL,
FULLTEXT KEY `index` (`name`,`text`,`tags`),
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

Помогите пжл.. Мне кажется, что я в цикле не так вывожу..

  Ответить  
 
 автор: cheops   (20.03.2011 в 21:13)   письмо автору
 
   для: (Sandr)   (20.03.2011 в 21:07)
 

>Мне кажется, что я в цикле не так вывожу..
Есть такое дело. Функция mysql_fetch_array() возвращает массив $sql, т.е. вам нужно выводить данные как-то так (в качестве ключей массива используйте названия столбцов таблицы)
<?php
  
...
  while(
$sql mysql_fetch_array($search)) 
  { 
    echo 
htmlspecialchars($sql['name'])."<br>"
    echo 
'<hr>'
  }
  ...
?>

  Ответить  
 
 автор: (Sandr)   (20.03.2011 в 21:27)   письмо автору
 
   для: cheops   (20.03.2011 в 21:13)
 

писал и name и text и tags. Но опять же ничего не выводится( Только почему
echo count($search);
выводит 1 я не пойму..

  Ответить  
 
 автор: cheops   (20.03.2011 в 21:37)   письмо автору
 
   для: (Sandr)   (20.03.2011 в 21:27)
 

А что в count()?

PS Чтобы узнать есть ли в результирующей таблице записи можно воспользоваться функцией mysql_num_rows().

  Ответить  
 
 автор: (Sandr)   (20.03.2011 в 21:41)   письмо автору
 
   для: cheops   (20.03.2011 в 21:37)
 

точно.. забыл про неё))

  Ответить  
 
 автор: (Sandr)   (20.03.2011 в 21:43)   письмо автору
 
   для: cheops   (20.03.2011 в 21:37)
 

Написал, теперь выводит 0.

  Ответить  
 
 автор: (Sandr)   (20.03.2011 в 21:51)   письмо автору
 
   для: cheops   (20.03.2011 в 21:37)
 

Странно. Ввёл для поиска другие данные, такие как "Рыбалка", "Психология" и мне вывело результаты (эти записи про психологию и рыбалку также были в бд). Но почему про арию не выводит. хм..

  Ответить  
 
 автор: cheops   (20.03.2011 в 22:02)   письмо автору
 
   для: (Sandr)   (20.03.2011 в 21:51)
 

У вас UTF-8, вообще поиск должен зависеть от регистра, т.е. "Ария" и "ария" - это должны восприниматься как разные слова.

  Ответить  
 
 автор: (Sandr)   (20.03.2011 в 22:19)   письмо автору
 
   для: cheops   (20.03.2011 в 22:02)
 

Да, я читал, и зменял запрос "Ария" на "ария" но результата небыло. А на другие записи всё норм)
Спасибо. Теперь буду использовать индексы))

  Ответить  
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования