MySQL match() против () - порядок по релевантности и столбцу?
Итак, я пытаюсь сделать полнотекстовый поиск по нескольким столбцам, что-то простое, как это:
SELECT * FROM pages WHERE MATCH(head, body) AGAINST('some words' IN BOOLEAN MODE)
Теперь я хочу упорядочить по релевантности (сколько слов найдено?), Что я смог сделать с чем-то вроде этого:
SELECT * , MATCH (head, body) AGAINST ('some words' IN BOOLEAN MODE) AS relevance
FROM pages
WHERE MATCH (head, body) AGAINST ('some words' IN BOOLEAN MODE)
ORDER BY relevance
Теперь наступает момент, когда я теряюсь, я хочу расставить приоритеты в head
колонка.
Я думаю, я мог бы сделать два столбца релевантности, один для head
и один для body
, но в этот момент я буду выполнять примерно один и тот же поиск в таблице три раза, и для этой функции важна производительность, поскольку запрос будет объединен и сопоставлен с другими таблицами.
Итак, мой главный вопрос: есть ли более быстрый способ поиска релевантности и расстановки приоритетов для определенных столбцов? (И в качестве бонуса возможно даже сделать подсчет релевантности числом раз, когда слова встречаются в столбцах?)
Любые предложения или советы будут великолепны.
Примечание: я буду запускать это на LAMP-сервере. (WAMP в локальном тестировании)
5 ответов
Это может придать повышенную актуальность той головной части, которую вы хотите. Это не удвоит его, но это может быть достаточно хорошо для вас:
SELECT pages.*,
MATCH (head, body) AGAINST ('some words') AS relevance,
MATCH (head) AGAINST ('some words') AS title_relevance
FROM pages
WHERE MATCH (head, body) AGAINST ('some words')
ORDER BY title_relevance DESC, relevance DESC
-- alternatively:
ORDER BY title_relevance + relevance DESC
Postgres- это альтернатива, которую вы также хотите изучить, если у вас есть возможность переключать ядро БД. Это позволяет установить вес операторов и поиграть с рейтингом.
Просто добавляю, кому может понадобиться.. Не забудьте переделать таблицу!
ALTER TABLE table_name ADD FULLTEXT(column_name);
Я никогда не делал этого, но, похоже,
MATCH (head, head, body) AGAINST ('some words' IN BOOLEAN MODE)
Должен придавать двойной вес спичкам, найденным в голове.
Просто прочитайте этот комментарий на странице документов, подумав, что он может быть полезен для вас:
Отправленный Патриком О'Лооном 9 декабря 2002 6:51
В документации следует отметить, что В БУЛЕВОМ РЕЖИМЕ почти всегда возвращается значение 1.0. Для того чтобы получить значимость, вам необходимо:
SELECT MATCH('Content') AGAINST ('keyword1 keyword2') as Relevance
FROM table
WHERE MATCH ('Content') AGAINST('+keyword1+keyword2' IN BOOLEAN MODE)
HAVING Relevance > 0.2
ORDER BY Relevance DESC
Обратите внимание, что вы делаете регулярный запрос на релевантность для получения коэффициентов релевантности в сочетании с предложением WHERE, в котором используется BOOLEAN MODE. BOOLEAN MODE предоставляет вам подмножество, которое удовлетворяет требованиям поиска BOOLEAN, запрос релевантности выполняет фактор релевантности, а предложение HAVING (в этом случае) гарантирует, что документ релевантен поиску (то есть документы, которые имеют оценку менее 0,2 считаются неактуальными). Это также позволяет заказывать по релевантности.
Это может или не может быть ошибкой в том, как работает IN BOOLEAN MODE, хотя комментарии, которые я читал в списке рассылки, показывают, что ранжирование релевантности в BOOLEAN MODE не очень сложно, поэтому он плохо себя предоставляет для фактического предоставления соответствующих документов. Кстати, я не заметил потери производительности при этом, так как похоже, что MySQL выполняет поиск FULLTEXT только один раз, даже если два предложения MATCH различны. Используйте EXPLAIN, чтобы доказать это.
Так что может показаться, что вам не нужно беспокоиться о двойном полнотекстовом поиске, хотя вам все равно следует "использовать EXPLAIN, чтобы доказать это"
Я тоже просто играл с этим. Один из способов добавить дополнительный вес - в области ORDER BY кода.
Например, если вы сопоставляете 3 разных столбца и хотите увеличить вес определенных столбцов:
SELECT search.*,
MATCH (name) AGAINST ('black' IN BOOLEAN MODE) AS name_match,
MATCH (keywords) AGAINST ('black' IN BOOLEAN MODE) AS keyword_match,
MATCH (description) AGAINST ('black' IN BOOLEAN MODE) AS description_match
FROM search
WHERE MATCH (name, keywords, description) AGAINST ('black' IN BOOLEAN MODE)
ORDER BY (name_match * 3 + keyword_match * 2 + description_match) DESC LIMIT 0,100;
Просто добавьте, что если вы используете настраиваемое ранжирование, не забудьте использовать HAVING вместо WHERE, чтобы уменьшить нагрузку.
SELECT MATCH(x,y) AGAINST (? IN BOOLEAN MODE) AS r1,
MATCH(z) AGAINST (? IN BOOLEAN MODE) AS r2,
...
FROM table
HAVING (r1 + r2) > 0
ORDER BY (r1 * 3 + r2) DESC
LIMIT 10