2012-01-26 3 views
11

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

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

Есть ли способ унифицировать релевантность, чтобы результаты из всех трех таблиц имели сопоставимую релевантность?

+0

Логически это кажется хорошим местом для использования союзных и подсетов, которые выбираются с совпадением; но я никогда не использовал его для поиска таким образом; поэтому я сомневаюсь, что это ЛУЧШИЙ путь. – xQbert

+0

был бы какой-нибудь способ для веса? просто простое умножение – bowlerae

+0

Я задавался вопросом о нормализации наивысшей релевантности для 1, но все еще бросает результаты на несколько таблиц. – michael

ответ

20

Да, вы можете очень хорошо их объединить с помощью поисковой системы, такой как Apache Lucene и Solr.

http://lucene.apache.org/solr/

Если вам нужно сделать, это только в MySQL, вы можете сделать это с помощью UNION. Вероятно, вы захотите подавить любые нулевые результаты.

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

Например, предположим, что вы хотите, чтобы статьи были наиболее важными, события были важными, а страницы были наименее важными. Вы можете использовать мультипликатор, как это:

set @articles_multiplier=3; 
set @events_multiplier=2; 
set @pages_multiplier=1; 

Вот рабочий пример, который вы можете попробовать это демонстрирует некоторые из этих методов:

Создать образец данные:

create database d; 
use d; 

create table articles (id int primary key, content text) ENGINE = MYISAM; 
create table events (id int primary key, content text) ENGINE = MYISAM; 
create table pages (id int primary key, content text) ENGINE = MYISAM; 

insert into articles values 
(1, "Lorem ipsum dolor sit amet"), 
(2, "consectetur adipisicing elit"), 
(3, "sed do eiusmod tempor incididunt"); 

insert into events values 
(1, "Ut enim ad minim veniam"), 
(2, "quis nostrud exercitation ullamco"), 
(3, "laboris nisi ut aliquip"); 

insert into pages values 
(1, "Duis aute irure dolor in reprehenderit"), 
(2, "in voluptate velit esse cillum"), 
(3, "dolore eu fugiat nulla pariatur."); 

сделать доступную для поиска:

ALTER TABLE articles ADD FULLTEXT(content); 
ALTER TABLE events ADD FULLTEXT(content); 
ALTER TABLE pages ADD FULLTEXT(content); 

Используйте UNION для поиска всех этих таблиц:

set @target='dolor'; 

SELECT * from (
    SELECT 
    'articles' as 'table_name', id, 
    @articles_multiplier * (MATCH(content) AGAINST (@target)) as relevance 
    from articles 
    UNION 
    SELECT 
    'events' as 'table_name', 
    id, 
    @events_multiplier * (MATCH(content) AGAINST (@target)) as relevance 
    from events 
    UNION 
    SELECT 
    'pages' as 'table_name', 
    id, 
    @pages_multiplier * (MATCH(content) AGAINST (@target)) as relevance 
    from pages 
) 
as sitewide WHERE relevance > 0; 

Результат:

+------------+----+------------------+ 
| table_name | id | relevance  | 
+------------+----+------------------+ 
| articles | 1 | 1.98799377679825 | 
| pages  | 3 | 0.65545331108093 | 
+------------+----+------------------+ 
+0

Это потрясающе! У меня вопрос очень похожий, но мне нужны соответствующие матчи. не могли бы вы также взглянуть на него? http://stackoverflow.com/q/9953922/633513 – LordZardeck

+0

Вы УДИВИТЕЛЬНЫ! – Cogicero

+0

Спасибо за этот ответ !!!! – Marcky

2

(К сожалению, я хочу оставить это как комментарий к выше ответ, но я не хватает репутации комментировать)

Имейте в виду, что UNION в подзапросах очень плохо оптимизированы. Часто случается, когда вы хотите разбивать на страницы свои результаты, используя «LIMIT @page * 10, 10» в родительском запросе, тогда MySQL должен получить все результаты подзапросов, чтобы оценить родительский запрос.

Смежные вопросы