多个表上的mysql全文

时间:2010-11-19 16:09:54

标签: mysql full-text-search

我正在尝试在三个单独的表中进行全文搜索,并按相关性对结果进行排序。在我搜索答案期间,我发现我无法在多个表格中使用全文搜索。所以我为每个要搜索的列添加了单独的全文索引。现在的问题是我可以进行搜索,但我不能按照自己的意愿进行排序。

这是我的表格

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或sphinx,但我现在不打算使用它们。

提前致谢。

3 个答案:

答案 0 :(得分:34)

您应该能够在ORDER BY子句中添加t分数,分数和分数值。

试试这个:

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 :(得分:0)

@Ike Walker的解决方案很棒,但在我的情况下,我希望将每对搜索结果中的一对多结果汇总到一行。在这里重复@Ike Walker的解决方案就是我完成工作的方式:

架构:

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 

在这种情况下,title将有3x,body 2x是评论中匹配的值。

答案 2 :(得分:-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

但这可能会产生奇怪的结果,因为搜索文本只显示在章节中的内容可以显示在标题之前。

相关问题