2010-11-19 65 views
15

我正在嘗試在三個獨立的表中進行全文搜索並按照相關性對結果進行排序。在我搜索答案的過程中,我發現我無法在多個表中使用全文搜索。所以我爲我想搜索的每一列添加了一個單獨的全文索引。現在的問題是,我可以做搜索,但我不能按照自己的意願進行排序。多個表上的mysql全文搜索

這裏是我的表

CREATE TABLE books (
bookID int(11) NOT NULL AUTO_INCREMENT, 
title varchar(300) NOT NULL, 
authorID int(11) NOT NULL, 
FULLTEXT KEY title (title) 
) 

CREATE TABLE IF NOT EXISTS authors (
authorID int(11) NOT NULL AUTO_INCREMENT, 
authorNamevarchar(200) NOT NULL, 
FULLTEXT KEY authorName(authorName) 
); 

CREATE TABLE IF NOT EXISTS chapters (
chapterID int(11) NOT NULL AUTO_INCREMENT, 
bookID int(11) NOT NULL, 
content longtext NOT NULL, 
FULLTEXT KEY content (content) 
); 

我的SQL查詢。這是我卡住的地方。

SELECT *, 
MATCH(books.title) AGAINST('$q') as tscore, 
MATCH(authors.authorName) AGAINST('$q') as ascore 
MATCH(chapters.content) AGAINST('$q') as cscore 
FROM books 
LEFT JOIN authors ON books.authorID = authors.authorID 
LEFT JOIN chapters ON books.bookID = chapters.bookID 
WHERE 
MATCH(books.title) AGAINST('$q') 
OR MATCH(authors.authorName) AGAINST('$q') 
OR MATCH(chapters.content) AGAINST('$q') 
ORDER BY ???? DESC 

現在通過本查詢,我可以按標題,作者或內容進行排序。我想要做的是,將所有三列的相關性集中在一起,然後通過它來排列結果。

而且,是的,我知道像lucene或獅身人面像其他搜索引擎,但我現在不打算使用它們。

在此先感謝。

回答

30

您應該可以在ORDER BY子句中添加tscore,ascore和cscore值。

試試這個:

SELECT *, 
MATCH(books.title) AGAINST('$q') as tscore, 
MATCH(authors.authorName) AGAINST('$q') as ascore, 
MATCH(chapters.content) AGAINST('$q') as cscore 
FROM books 
LEFT JOIN authors ON books.authorID = authors.authorID 
LEFT JOIN chapters ON books.bookID = chapters.bookID 
WHERE 
MATCH(books.title) AGAINST('$q') 
OR MATCH(authors.authorName) AGAINST('$q') 
OR MATCH(chapters.content) AGAINST('$q') 
ORDER BY (tscore + ascore + cscore) DESC 
+1

。謝謝。 – keune 2010-11-19 18:39:05

+0

幫助我加載。謝謝! – youngcouple10 2012-02-28 21:23:35

+1

非常好,我需要我的項目! – NaturalBornCamper 2012-09-24 01:55:23

-1

這取決於你想要排序的東西。您可以通過作者,那麼標題,然後章內容與此

ORDER BY MATCH(authors.authorName) DESC ,MATCH(books.title) DESC ,MATCH(chapters.content) DESC 

的想法是,當你發現作者的名字,這是當它的稱號,這又是不是更相關的發現比更相關排序在章節文本中找到它。您還可以通過總與相關

ORDER BY MATCH(authors.authorName) + MATCH(books.title) + MATCH(chapters.content) DESC 

排序,但可能給奇怪的結果,因爲一些地方搜索文本只顯示了一章中的內容可以在標題前露面。

+0

不起作用我試過....你可以做匹配(..)反對(),它完全相同的事情做第二個查詢 – ITECH 2013-10-17 14:10:45

0

@Ike沃克的解決方案是偉大的,但在我的情況,我想了一個一對多的結果彙總到每個搜索結果的單行。 Riffing上@Ike沃克的解決方案在這裏就是我完成了任務:

模式:

T1: Articles 
T2: Comments (many comments to one article) 

指標:

ALTER TABLE articles ADD FULLTEXT title_index (title) 
ALTER TABLE articles ADD FULLTEXT body_index (body) 
ALTER TABLE comments ADD FULLTEXT comment_index (comment) 

SQL:

SELECT 
    articles.title, 
    SUM(MATCH(articles.title) AGAINST('$q') + 
    MATCH(articles.body) AGAINST('$q') + 
    MATCH(comments.comment) AGAINST('$q')) as relevance 
FROM 
    articles 
LEFT JOIN 
    comments ON articles.id = comments.article_id 
WHERE 
    MATCH(articles.title) AGAINST('$q') 
    OR MATCH(articles.body) AGAINST('$q') 
    OR MATCH(comments.comment) AGAINST('$q') 
GROUP BY 
    articles.id 
ORDER BY 
    relevance DESC 

注意:如果你想爲每個領域添加權重,你可以做類似的事情。

SUM((MATCH(articles.title) AGAINST('$q')*3) + 
     (MATCH(articles.body) AGAINST('$q')*2) + 
     MATCH(comments.comment) AGAINST('$q')) as relevance 

在這種情況下,標題將有3倍,正文2倍的註釋匹配的值。