Упорядочить по релевантности, используя логический полнотекстовый поиск - PullRequest
2 голосов
/ 13 августа 2010

У меня проблемы с использованием полнотекстового поиска MySQL и возвращением результатов в порядке релевантности.Я должен использовать логический полнотекстовый поиск, который не возвращает результаты в порядке релевантности.Однако мне нужны эти результаты в порядке актуальности.Если я попытаюсь добавить предложение order by в конце запроса, запрос приведет к использованию сортировки файлов, что делает запрос невероятно медленным (более чем в 1000 раз медленнее, чем без него).Я не уверен, что можно сделать.

Вот мой запрос:

SELECT g.id, MATCH(g.searchable_name) AGAINST ('test*' IN BOOLEAN MODE) AS relevance
 FROM games g
 WHERE MATCH(g.searchable_name) AGAINST ('test*' IN BOOLEAN MODE)
 ORDER BY relevance DESC
 LIMIT 0, 31

Заранее спасибо.

1 Ответ

0 голосов
/ 08 февраля 2017

Сначала вы должны учитывать, что IN BOOLEAN MODE не возвращает счет , вместо этого он возвращает двоичный код (1 = найдено, 0 = не найдено):

mysql>SELECT
        topic_id,
        MATCH(topic_text) AGAINST('+tuning' IN BOOLEAN MODE) AS binary
    FROM
        topics_search
    LIMIT 10
+----------+----------+
| topic_id | binary   |
+----------+----------+
| 2        | 0        |
| 4        | 0        |
| 5        | 0        |
| 6        | 1        |
| 7        | 0        |
| 8        | 0        |
| 11       | 0        |
| 12       | 0        |
| 13       | 0        |
| 14       | 0        |
+----------+----------+
10 rows in set (9 ms)

Только естественный полнотекстовый поиск способен генерировать оценку (модификатор IN NATURAL LANGUAGE MODE не указан, так как это режим по умолчанию):

mysql>SELECT SQL_NO_CACHE
        topic_id,
        MATCH(topic_text) AGAINST('tuning') AS score
    FROM
        topics_search
    WHERE
        host_id = 1
    ORDER BY
        score DESC
    LIMIT 10
+--------------------+--------------------+
| topic_id           | score              |
+--------------------+--------------------+
| 153257             | 5.161948204040527  |
| 17925              | 4.781417369842529  |
| 66459              | 4.648380279541016  |
| 373176             | 4.570812702178955  |
| 117173             | 4.55166482925415   |
| 167016             | 4.462575912475586  |
| 183286             | 4.4519267082214355 |
| 366132             | 4.348565101623535  |
| 95502              | 4.293642520904541  |
| 29615              | 4.178250789642334  |
+--------------------+--------------------+
10 rows in set (478 ms)

Примечание: Невероятно медленно, потому что score не может иметь индекс.

Так что вам нужен естественный поиск для сортировки по счету. Но естественный поиск не поддерживает операторы, такие как *. И теперь у нас есть дилемма, потому что бесполезно искать tunin* в BOOLEAN и выполнять параллельный поиск в NATURAL, используя ключ tunin, так как ни один текст не будет включать это частичное слово.

mysql>SELECT SQL_NO_CACHE
        topic_id,
        MATCH(topic_text) AGAINST('tunin') AS score
    FROM
        topics_search
    WHERE
        MATCH(topic_text) AGAINST('tunin*' IN BOOLEAN MODE)
    AND
        MATCH(topic_text) AGAINST('tunin') > 0
    ORDER BY
        score DESC
    LIMIT 10
Empty set (170 ms)

Заключение
Невозможно выполнить поиск с помощью оператора подстановочного знака и отсортировать результаты по релевантности.

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

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