[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: Экранирование операторов при полнотекстовом поиске
seka19
Здравствуйте.

В общем, задача следующая.
Есть таблица на 300к строк, весом около 300мб. В перспективе - более 1кк строк.
И по ней необходимо проводить поиск по текстовому полю.
В процессе проработки алгоримов, пока данные были тестовые, никаких проблем не было, делал так:
SELECT * FROM `table` WHERE `field` LIKE '%text-text-text-text%';


Теперь, в процессе окончательного тестирования проекта, выяснилось, что такие запросы иногда выполняются по 5-6 секунд.

Решил использовать полнотекстовый поиск, с которым ранее опыта работа не имел. В общем, почитал справки и маны, всё понятно и хорошо. Конкретно, я знаю всё, что есть тут: http://www.mysql.ru/docs/man/Fulltext_Search.html
Правда по ходу выяснил, что при полнотекстовом поиске существует понятие релевантности и резльутат запроса
SELECT * FROM `table` WHERE MATCH(`field`) AGAINST('text-text-text-text');

будет не таким, как в случае с LIKE.

Далее я узнал про директиву IN BOOLEAN MODE и операторы и задача теперь почти решена, вот так:
SELECT * FROM `table` WHERE MATCH(`field`) AGAINST('"text-text-text-text"' IN BOOLEAN MODE);


И как бы всё супер, но остался один важный вопрос, ответ на который я никак не могу найти: КАК ЭКРАНИРОВАТЬ ЭТИ ОПЕРАТОРЫ?
Например, искомый текст:
Цитата
Омской области "Дирекция программ в сфере оздоровления

И ковычка в нём работает как оператор. Который нужно экранировать.

Как временное решение, я придумал вот такой способ:
SELECT * FROM `table` WHERE MATCH(`field`) AGAINST('+"Омской области "+"Дирекция программ в сфере оздоровления"' IN BOOLEAN MODE);

Т.е. перед первой двойной ковычкой-оператором (означающим поиск точного вхождения подстроки) ставится + (типа "обязательно"), и затем в каждом месте, где есть операторы, которые нужно экранировать (вот эти символы: + - < > ( ) ~ * "), они заменяются на "+" (ковычка, плюс, ковычка) - таким образом в фразе, заключённой в двойные ковычки, происходит как бы разрыв в месте, где встретился ненужный оператор.

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

ЗЫ: где-то мелькала мысль, что помогает, если заменить эти операторы на их html-сущности. Но замена " на &quot; или на &# 34; результата не дала - такой запрос вооще ничего не находит.

Кто знает, как экранировать эти операторы, или где об этом почитать? Заранее спасибо.



Спустя 12 минут, 53 секунды (28.09.2011 - 20:34) Winston написал(а):
Попробуй
"SELECT * FROM `table` WHERE MATCH(`field`) AGAINST('" .addcslashes(mysql_real_escape_string('"Омской области "Дирекция программ в сфере оздоровления"'), '%_\\\''). "' IN BOOLEAN MODE)";

Спустя 2 часа, 9 минут, 58 секунд (28.09.2011 - 22:44) seka19 написал(а):
НУ, получилось в итоге вот это:
MATCH(`field`) AGAINST('\\"Омской области \\"Дирекция программ в сфере оздоровления\\"' IN BOOLEAN MODE)

И как бы безрезультатно. Т.е. результатов слишком много: как будто это даже не BOOLEAN MODE.

ЗАТО! Чисто случайно обнаружил, что если из этой фразы просто убрать ковычку, то результат получается как раз таким, как нужно!
Вероятно, это связано с тем фактом, что полнотекстовый поиск производится только по словам, которые состоят из букв, цифр и символов _ и '
Просто из всех прочитанных материалов я так и не уловил, касается ли это правило поиска в BOOLEAN MODE, или нет. Но, видимо, да.

В общем, всем спасибо, вопрос закрыт.
Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2025 Invision Power Services, Inc.