Я пытаюсь создать крошечную поисковую систему для упражнений, используя mysql.
Каждое упражнение может иметь произвольное количество тегов поиска.
Вот моя структура данных:
TABLE exercises
ID
title
TABLE searchtags
ID
title
TABLE exerciseSearchtags
exerciseID -> exercises.ID
searchtagID -> searchtags.ID
...где trainingSearchtags — таблица соединения «многие ко многим», выражающая отношения между упражнениями и тегами поиска.
Поисковая система принимает неизвестное количество ключевых слов, введенных пользователем.
Я хотел бы ранжировать результаты поиска на основе количества совпадений ключевого слова / тега поиска.
Вот sql, который я сейчас использую для выбора упражнений. И правила CASE, и правила WHERE генерируются динамически, по одному для каждого ключевого слова. Так, например, если пользователь вводит 3 ключевых слова, будет 3 правила CASE и 3 правила WHERE.
SELECT
exercises.ID AS ID,
exercises.title AS title,
(
(CASE WHEN searchtags.title LIKE CONCAT('%',?,'%') THEN 1 ELSE 0 END)+
(CASE WHEN searchtags.title LIKE CONCAT('%',?,'%') THEN 1 ELSE 0 END)+
...etc...
(CASE WHEN searchtags.title LIKE CONCAT('%',?,'%') THEN 1 ELSE 0 END)
) AS relevance
FROM
exercises
LEFT JOIN exerciseSearchtags
ON exerciseSearchtags.exerciseID = exercises.ID
LEFT JOIN searchtags
ON searchtags.ID = exerciseSearchtags.searchtagID
WHERE
searchtags.title LIKE CONCAT('%',?,'%') OR
searchtags.title LIKE CONCAT('%',?,'%') OR
...etc...
searchtags.title LIKE CONCAT('%',?,'%')
GROUP BY
exercises.ID
ORDER BY
relevance DESC
Это почти работает. Однако результаты ранжируются не в том порядке, в котором я ожидал.
Мое лучшее предположение о том, почему это происходит, заключается в том, что показатель релевантности рассчитывается ДО того, как строки будут сгруппированы по ИД упражнения. Таким образом, если левое соединение приводит к тому, что определенное упражнение появляется в наборе результатов 10 раз, а другое упражнение появляется 4 раза, то первое упражнение может получить более высокий показатель релевантности, даже если оно может не иметь больше совпадений ключевого слова / поискового тега.
Есть ли у кого-нибудь какие-либо предложения/советы о том, как я могу предотвратить это/исправить это?
Заранее спасибо за вашу помощь.