У меня есть список ключевых слов в поле под названием «ключевые слова» в базе данных MYSQL. Например, поле ключевых слов в записи содержит 3 образца записей
KEYWORD LIST 1: tree,apple,banana,cherry,flower,red apple,pink cherry,cat,mouse
KEYWORD LIST 2: cat,mouse,apple,red apple,flower,red appleberry
KEYWORD LIST 3: apple, red appleberry, flower
Список ключевых слов НЕ является массивом — это просто текстовое поле в базе данных mysql, в котором есть много других полей.
Когда я запускаю запрос MYSQL SELECT из того, что я видел «до сих пор», есть два способа: а) например, %% b) сопоставлять с
Допустим, я хочу выполнить запрос к слову «яблоко»
SELECT *, где ключевые слова, такие как «% apple%» из таблицы
Это приведет к появлению записей, которые содержат слово «яблоко», включая запись выше, но это не обязательно даст мне последовательность выше или ниже. Я должен был сделать фильтрацию результатов пост-запроса.
Предположим, я был более подробен в своем запросе и выбрал «красное яблоко», он все равно будет показывать совпадение, но я не обязательно получу, чтобы KEYWORD LIST 1 был более релевантным, чем 2 или 3.
Кто-то предложил использовать матч против
SELECT *, MATCH(Keywords) AGAINST('apple') AS Score
FROM table
WHERE Keywords like '%red apple%'
ORDER BY score DESC;
Это, безусловно, движется в правильном направлении — однако это не приведет к сортировке результатов по точному соответствию, которое будет сочтено более актуальным. Релевантность будет зависеть от того, сколько повторений слова «яблоко» появилось в списке ключевых слов (это старая причина, по которой все поисковые системы вообще игнорировали ключевые слова) — вы понимаете, куда я иду с этим?
То, что я ищу, — это обрабатывать большую часть логики в MYSQL, а не считывать ее в массив и обрабатывать в PHP, как предлагали другие. Отсюда и этот упрощенный пример.
Вот как должен выглядеть запрос:
1) если мой запрос ‘apple’, список ключевых слов 1 должен отображаться первым
2) если мой запрос «красное яблоко», то список ключевых слов 2 должен отображаться первым, потому что слово «красное яблоко» находится ближе к ПЕРЕДНЕМУ списка ключевых слов — ближе к началу строки.
НО из-за НРАВИТСЯ %%
Список ключевых слов 3 будет отображаться даже в том случае, если вместо «красного яблока» было выбрано «красное яблоко»
(Было бы проще всего, если бы в MySQL была какая-то функция «взорвать», чтобы вы могли указывать запятую (‘,’) в качестве разделителя в совпадении, но я не знаю ни одного такого метода, не так ли? Я должен прочитать весь список результатов в массив, а затем разбить их на PHP.
3) Предположим, я ищу «красное яблоко» и вот ошибка: у меня все еще есть совпадение с «красным яблоком» (запись 3) — я этого не хочу. Запись 2 должна появиться, а затем запись 1 и даже не показывать запись 3.
Это обсуждение и запрос. У кого-нибудь есть предложения?
МОЙ СОБСТВЕННЫЙ ОТВЕТ:
включите запятую в запросе
вместо поиска «красное яблоко» ищите «красное яблоко»
но что если пользователь поместит пробел между — или, если он находится в конце списка ключевых слов?
ВОПРОС:
Как мы можем искать конкретный SCORE в текстовом поле с разделителями-запятыми в MYSQL, которое использует точное слово (а не фрагмент), чтобы составить ORDERED список результатов.
В каждой попытке до сих пор список ключевых слов 3 будет отображаться выше, чем 2, хотя красное яблоко и красное яблоко — это две разные фразы, разделенные запятыми.
Спасибо! Давайте обсудим!
Для небольшого проекта вы можете сделать что-то вроде этого
SELECT *,
case when keyword like '%red apple%' then 1 else 0 end exact_match,
MATCH(Keywords) AGAINST('apple') AS Score
FROM table
where keywords like '%apple%'
ORDER BY exact_match DESC, score DESC;
Других решений пока нет …