2012-01-26 52 views
11

我的任務是創建一個全站搜索功能。搜索需要看文章,事件和頁面內容跨多個表的Mysql全文搜索相關性

我已經在MySQL中使用MATCH()/ AGAINST()之前,知道如何獲得結果的相關性,但據我所知,相關性是獨特的到搜索(內容,行數等),來自文章表格的結果的相關性不會匹配來自事件表格的結果的相關性。

無論如何要統一相關性,以便所有三個表的結果具有可比性相關性嗎?

+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

(對不起,我要離開這個作爲上述答案的評論,但我沒有足夠的信譽評論)

要知道,聯盟的子查詢是非常糟糕的優化。通常情況下,當您想要在父查詢中使用「LIMIT @page * 10,10」對結果進行分頁時,那麼MySQL必須從子查詢中獲得全部的結果以評估父查詢。