Как разрешить полнотекстовый поиск с дефисами в поисковом запросе

У меня есть ключевые слова, такие как "некоторые или другие", где дефисы имеют значение при поиске в моей базе данных mysql. В настоящее время я использую полнотекстовую функцию.

Есть ли способ избежать дефиса? Я знаю, что один из вариантов - закомментировать #define HYPHEN_IS_DELIM в файле myisam / ftdefs.h, но, к сожалению, мой хост не позволяет этого. Есть ли другой вариант там?

Изменить 3-8-11 Вот код, который я сейчас имею:

$search_input = $_GET['search_input'];
$keyword_safe = mysql_real_escape_string($search_input);
$keyword_safe_fix = "*'\"" . $keyword_safe . "\"'*";


$sql = "
    SELECT *,
        MATCH(coln1, coln2, coln3) AGAINST('$keyword_safe_fix') AS score
        FROM table_name
    WHERE MATCH(coln1, coln2, coln3) AGAINST('$keyword_safe_fix')
    ORDER BY score DESC
";

4 ответа

Отсюда http://dev.mysql.com/doc/refman/5.0/en/fulltext-search.html

Одним из решений для поиска слова с дефисами или дефисами является использование ПОЛНОГО ТЕКСТОВОГО ПОИСКА В БУЛЕВОМ РЕЖИМЕ и включение слова с дефисом / тире в двойных кавычках.

Или отсюда http://bugs.mysql.com/bug.php?id=2095

Есть еще один обходной путь. Недавно оно было добавлено в руководство: "Изменить файл набора символов: для этого не требуется перекомпиляция. Макрос true_word_char () использует таблицу" тип символов "для различения букв и цифр от других символов. Вы можете редактировать содержимое одним из XML-файлы набора символов, указывающие, что "-" является "буквой". Затем используйте заданный набор символов для ваших индексов FULL TEXT ".

Не пробовал это самостоятельно.

Изменить: вот еще несколько дополнительных сведений здесь http://dev.mysql.com/doc/refman/5.0/en/fulltext-boolean.html

Фраза, заключенная в символы двойной кавычки ("" "), соответствует только строкам, которые содержат фразу буквально, как она была набрана. Полнотекстовая машина разбивает фразу на слова и выполняет поиск по индексу FULL TEXT для слов. До MySQL 5.0.3 механизм затем выполнял поиск подстроки для фразы в найденных записях, поэтому совпадение должно включать в фразу несловесные символы. Начиная с MySQL 5.0.3, несловные символы не должны совпадать точно: Поиск по фразе требует, чтобы совпадения содержали точно такие же слова, что и фраза, и в том же порядке, например, "тестовая фраза" соответствует "тест, фраза" в MySQL 5.0.3, но не ранее.

Если фраза не содержит слов, которые есть в индексе, результат будет пустым. Например, если все слова являются либо стоп-словами, либо короче минимальной длины индексированных слов, результат будет пустым.

Некоторые люди предложили бы использовать следующий запрос:

SELECT id 
FROM texts
WHERE MATCH(text) AGAINST('well-known' IN BOOLEAN MODE)
HAVING text LIKE '%well-known%';

Но при этом вам нужно много вариантов в зависимости от используемых полнотекстовых операторов. Задача: реализовать запрос как +well-known +(>35-hour <39-hour) working week*, Слишком сложный!

И не забудьте про лен по умолчанию ft_min_word_len поэтому поиск up-to-date только возвращается date в ваших результатах.

выходка

Из-за этого я предпочитаю трюк, так что конструкции с HAVING и т.д. не нужны вообще:

  1. Вместо добавления следующего текста в таблицу базы данных:

     "Современный колдун" - это известный научно-фантастический рассказ. 
    скопируйте дефисные слова без переносов в конец текста внутри комментария:
     "Современный колдун" - это известный научно-фантастический рассказ. <!-- UptoDate wellknown -->

  2. Если пользователи ищут up-to-date удалите дефис в запросе sql:
    MATCH(text) AGAINST('uptodate ' IN BOOLEAN MODE)

По этому вы можете найти пользователя up-to-date одним словом вместо получения всех результатов, которые содержат только date (так как ft_min_word_len убийств up а также to).

Конечно перед тобой echo тексты, которые вы должны удалить <!-- ... --> Комментарии.

преимущества

  • запрос проще
  • пользователь может использовать все полнотекстовые операторы как обычно
  • запрос быстрее.
  • Если пользователь ищет -well-known +science MySQL рассматривает это как not include *well*, could include *known* and must include *science*, Это не то, что ожидал пользователь. Трюк тоже это решает (так как SQL-запрос ищет -wellknown +science)

Может быть, проще использовать Binary оператор.

SELECT * 
FROM your_table_name 
WHERE BINARY your_column = BINARY "Foo-Bar%AFK+LOL"

http://dev.mysql.com/doc/refman/5.0/en/cast-functions.html

BINARY Оператор преобразует строку, следующую за ней, в двоичную строку. Это простой способ заставить сравнение столбцов выполнять побайтово, а не посимвольно. Это делает сравнение чувствительным к регистру, даже если столбец не определен как BINARY или же BLOB, BINARY также приводит к тому, что конечные пробелы будут значительными

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

Затем я отображаю return колонка.

Это означает, что у меня есть две копии данных в моей базе данных, но для меня этот компромисс стоит того. Моя таблица FT занимает всего ~500 тыс. Строк, поэтому в моем случае это не имеет большого значения.

Это может звучать странно, но, немного поработав с этим, я понял, что получаю желаемые результаты, удалив дефис из поискового выражения. Например, если я ищу слово "разделены словами"

SELECT * FROM table WHERE MATCH(column) AGAINST ('word separated');

возвращает экземпляры "разделенных словами" по мере необходимости. Это также возвращает другие случаи разделенного и слова, но добавляя + Оператор для каждого слова достигает дефис поиска.

SELECT * FROM table WHERE MATCH(column) AGAINST ('+word +separated');
Другие вопросы по тегам