我正在尝试在三个单独的表中进行全文搜索,并按相关性对结果进行排序。在我搜索答案期间,我发现我无法在多个表格中使用全文搜索。所以我为每个要搜索的列添加了单独的全文索引。现在的问题是我可以进行搜索,但我不能按照自己的意愿进行排序。
这是我的表格
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,但我现在不打算使用它们。
提前致谢。
答案 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
但这可能会产生奇怪的结果,因为搜索文本只显示在章节中的内容可以显示在标题之前。