如何跨多个表实现MySQL全文搜索?

如何跨多个表实现MySQL全文搜索?,mysql,full-text-search,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 K

我试图在三个独立的表格中进行全文搜索,并根据相关性对结果进行排序

在搜索答案的过程中,我发现我不能在多个表中使用全文搜索。因此,我为要搜索的每一列添加了单独的全文索引

现在的问题是,我可以做搜索,但我不能做排序,因为我想

这是我的桌子:

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)
);
这是我的MySQL查询,我被卡住了:

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

这取决于你想按什么排序。您可以按作者、标题、章节内容进行排序

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

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

您应该能够在
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

@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:

注意:如果要为每个字段添加权重,可以执行以下操作

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

在本例中,标题的注释值是匹配值的3倍,正文的2倍。

非常好,这是我的项目所需要的!您可以将排序中的每个字段的权重乘以它们,例如:ORDER by(tscore*3+ascore*2+cscore)description美元符号“$”的用途是什么?不起作用我试过了…您可以按匹配(..)对()排序,这与第二个查询的作用相同您获得了向上投票。一个是我的!您的代码是一个出色的工作示例。原来的帖子已经快11年了!!!但在2021年,这个查询仍然有效!很有魅力,谢谢
SUM((MATCH(articles.title) AGAINST('$q')*3) + 
        (MATCH(articles.body) AGAINST('$q')*2) + 
        MATCH(comments.comment) AGAINST('$q')) as relevance