Полнотекстовый поиск в MySQL - PullRequest
2 голосов
/ 01 апреля 2011

Я новичок в "поиске" в MySQL, и у меня есть некоторые задачи, которые я не знаю, как их решить наилучшим образом.

У меня есть следующая MySQL-таблица в моей базе данных.

delimiter $$

CREATE TABLE `authors` (
  `id` int(11) NOT NULL,
  `name` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
  `count` int(11) NOT NULL DEFAULT '1',
  PRIMARY KEY (`id`),
  UNIQUE KEY `name_UNIQUE` (`name`),
  FULLTEXT KEY `name_fulltext` (`name`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci$$

Задача: В HTML-форме я хочу ввести имя, скажем, «Джон Доу».Это имя следует искать в этой таблице, в столбце «имя».Я хочу, чтобы запрос возвращал все похожие имена, такие как "John Due" или "John Doé" и так далее.Таким образом, пользователь может выбрать из списка правильное имя.Иногда люди хотят найти такое имя, как «Джон ван Доу» (стиль Нидерландов).Это также должно отображаться в списке.

Как это лучше всего достигается?Или мне лучше спросить.Это возможно?=) Я, кстати, использую cgi-скрипт на python, поэтому доступны любые модули, которые может предоставить python.

Другой вопрос: как мне посмотреть «Джон» или «Доу»?Каждое имя, в котором есть «Джон», должно быть отображено.Я попробовал "ГДЕ НАМ НРАВИТСЯ" Джон "", но это слишком медленно.Есть ли более быстрый способ?

Спасибо за любые предложения.

Ответы [ 2 ]

1 голос
/ 01 апреля 2011

Задача: В HTML-форме я хочу ввести имя, скажем, «Джон Доу».Это имя следует искать в этой таблице, в столбце «имя».Я хочу, чтобы запрос возвращал все похожие имена, такие как "John Due" или "John Doé" и так далее.Таким образом, пользователь может выбрать из списка правильное имя.Иногда люди хотят найти такое имя, как «Джон ван Доу» (стиль Нидерландов).Это также должно отображаться в списке.

MySQL не поддерживает словари синонимов, поэтому вы должны предоставить его самостоятельно.

Yahoo API предоставляет услугу исправления заклинаний, которую выможно использовать, отправив запрос, подобный следующему:

SELECT  *
FROM    search.spelling
WHERE   query='juhn doe'

, используя этот URL:

http://query.yahooapis.com/v1/public/yql?q=SELECT%20%20*%20%20FROM%20search.spelling%20WHERE%20query%20%3D%20'juhn%20doe'&format=json&diagnostics=true&callback=cbfunc

Как только вы получите список синонимов, вы можете искать их, используяэтот запрос к MySQL:

SELECT  *
FROM    authors
WHERE   MATCH(name) AGAINST ('(+juhn +doe) (+john +doe)' IN BOOLEAN MODE)

John Doé будет возвращен этим, так как вы используете UTF8_GENERAL_CI, который не зависит от регистра и акцента.

Если вы хотите посмотреть простодля John используйте этот запрос:

SELECT  *
FROM    authors
WHERE   MATCH(name) AGAINST ('+john' IN BOOLEAN MODE)

Кроме того, убедитесь, что для параметра ft_min_word_len установлено разумное значение (лучше всего 1) в my.cnf.

По умолчанию 4, что означает, что никакие трехбуквенные фамилии (например, Doe) не будут проиндексированы.

0 голосов
/ 01 апреля 2011

Одним из способов решения этой проблемы является создание канонической формы для имен. Каноническое имя будет одинаковым для всех похожих имен. Затем, когда вы хотите найти Джона Доу или Джона Доу или что-то еще, вы сначала сгенерируете каноническое имя, а затем выполните поиск по нему.

Конечно, создать алгоритм канонизации человеческих имен очень сложно, если вы хотите, чтобы такие вещи, как Doe и Due соответствовали друг другу. Простое базовое решение, которое позаботится о других упомянутых вами случаях, состоит в том, чтобы убрать все акценты (à -> a) и удалить von , van и т.д.

...