Как отсортировать результаты полнотекстового поиска MYSQL по релевантности - PullRequest
23 голосов
/ 19 июня 2009

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

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

$query="SELECT * from `vocabulary` WHERE translation = 'word' OR translation LIKE '%word%'";

Результаты, которые он возвращает, являются исчерпывающими в том смысле, что они включают все соответствующие строки. Тем не менее, они не сортируются в каком-либо определенном порядке, и я хотел бы, чтобы те с точным соответствием отображались первыми, когда я печатал результаты в PHP. Как это:


1 | слово <-точное совпадение <br /> 2 | кроссворд <- частичные совпадения отсортированы по алфавиту / <br /> 3 | слова
4 | словарь


Большое спасибо заранее за вашу помощь.

-macspacejunkie

Ответы [ 5 ]

29 голосов
/ 19 июня 2009

LIKE - это не полнотекстовый поиск . В полнотекстовом поиске MATCH(...) AGAINST(...) возвращает оценку соответствия, которая может быть приблизительно равна значимости.

22 голосов
/ 19 июня 2009

Вы можете получить хороший поиск по релевантности, создав полнотекстовый индекс, а затем сопоставив его с поисковым термином.

Так что-то вроде этого должно работать.

ALTER TABLE `vocabulary` ADD FULLTEXT INDEX `SEARCH`(`translation`);

SELECT *, MATCH(translation) AGAINST ('+word' IN BOOLEAN MODE) AS relevance 
FROM `vocabulary`
WHERE MATCH(translation) AGAINST ('+word' IN BOOLEAN MODE)
ORDER BY relevance DESC

Дополнительную информацию можно найти в Справочном руководстве по MySQL .

15 голосов
/ 19 июня 2009
SELECT * from vocabulary 
WHERE translation like 'word'  
union all
SELECT * from vocabulary 
WHERE translation LIKE '%word%' and translation not like 'word'  

сначала перечислит точные совпадения

5 голосов
/ 05 марта 2010

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

Я делаю два оператора MATCH () ПРОТИВ () в выборке и объединяю оценки для каждого, чтобы сформировать общую релевантность. Назначение разных множителей позволяет мне настроить importnace каждого набора результатов.

Мой первый MATCH () будет проверять по буквальному (или точному) поисковому запросу, используя двойные кавычки Мой второй матч будет проверяться нормально. Я применяю более высокий множитель к первому совпадению, поэтому он должен иметь более высокое значение релевантности, если он найден.

Примерно так.

SELECT *, ((MATCH(indexes) AGAINST ('"search_terms"' IN BOOLEAN MODE) * 10)  
           + (MATCH(indexes) AGAINST ('search_terms' IN BOOLEAN MODE) * 1.5)) AS relevance  
FROM ...
WHERE ...  
      AND (MATCH (indexes) AGAINST ('"search_terms"' IN BOOLEAN MODE) > 0  
           OR MATCH (indexes) AGAINST ('search_terms' IN BOOLEAN MODE) > 0)  
      ...
ORDER BY relevance DESC

Если вы запустите функцию EXPLAIN, чтобы показать, как работает запрос, вы обнаружите, что дополнительные предложения MATCH () AGAINST () фактически не добавляют никаких накладных расходов к запросу из-за того, как работает MySQL.

2 голосов
/ 05 марта 2016

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

SELECT * 
FROM vocabulary
WHERE translation LIKE '%word%'
ORDER BY translation <> 'word', translation;

Если translation равно 'word', оно будет в верхней части результатов. Это потому, что translation <> 'word' будет 0 , когда точное совпадение будет предшествовать 1 , которое будет возвращено для всех остальных результатов. Остальные результаты будут отсортированы в алфавитном порядке после этого из-за , translation.

В этом запросе не выполняется два запроса, как в случае выбранного ответа с UNION. Кроме того, вашему запросу не требуется translation = 'word' OR translation LIKE '%word%', так как вторая половина всегда будет выполняться и является надмножеством первой части.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...