Я создал таблицу MYSQL, используя следующий запрос:
CREATE TABLE IF NOT EXISTS `test` (
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
`name` VARCHAR(255) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY (`name`),
FULLTEXT INDEX(`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
И иметь следующие строки:
id | name
----------
1 | Acer Liquid Z6 Plus
2 | Acer Liquid Z6
3 | Acer Liquid X2
Я хочу использовать запрос MATCH
для поиска Acer Liquid Z6
, поэтому я выполнил следующий запрос:
SELECT * FROM `test` WHERE MATCH(name) AGAINST('acer liquid z6' IN NATURAL LANGUAGE MODE)
Запрос почему-то в качестве первого результата возвращает Acer Liquid Z6 Plus
:
id | name
----------
1 | Acer Liquid Z6 Plus
2 | Acer Liquid Z6
3 | Acer Liquid X2
Таким образом, полнотекстовый индекс сначала не возвращает наиболее релевантный результат. Есть ли более надежный способ поиска по индексу или заставить совпадение сначала возвращать наиболее релевантный результат?
Когда MySQL создает полнотекстовый индекс, он не индексирует все слова. Есть несколько различных параметров - что определяет границу слова, какие символы разрешены в слове. И два самых важных:
Минимальная длина слова - 3 или 4, в зависимости от механизма хранения. В любом случае 'z6'
игнорируется. документация - хорошее место для начала понимания этих параметров.
Вам нужно будет установить для параметра соответствующее значение и перестроить индекс.
Это не проблема. Полнотекстовый поиск сопоставляет слова с указанными вами столбцами, поскольку первая строка соответствует словам, которые она добавляется в список или массив результатов. Если бы ваши данные хранились вот так
id | название
1 | Acer Liquid Z6
2 | Acer Liquid Z6 Plus
3 | Acer Liquid X2
Тогда первая возвращенная строка будет Acer Liquid Z6.
Кроме того, вы можете играть с минимальной длиной слова, чтобы получить удовольствие. Но я не вижу в этом проблемы. Вы всегда можете отфильтровать список с помощью внутреннего кода.
«Если бы ваши данные хранились вот так», вот в чем проблема, данные не отсортированы таким образом, чтобы гарантировать получение ожидаемого результата в первую очередь. Проблема в том, что это параметр URL, и я хочу сопоставить этот параметр с правильной записью из базы данных, а не с фактическим поиском. Он должен быть похож на идентификатор строки, но не являться идентификатором. Кажется, изменение минимальной длины слова решит эту проблему, но я нахожусь на общем хостинге, поэтому моим вторым решением было бы сохранить параметр URL-адреса в базе данных (если нет другого решения)
Как бы то ни было, поиск MySQL FULLTEXT странно работает с небольшими тестовыми наборами данных. Также по умолчанию игнорируются «слова» короче трех символов.