How to implement a MySQL fulltext search across multiple tables? How to implement a MySQL fulltext search across multiple tables? mysql mysql

How to implement a MySQL fulltext search across multiple tables?


You should be able to add the tscore, ascore, and cscore values in the ORDER BY clause.

Try this:

SELECT *,   MATCH(books.title) AGAINST('$q') as tscore,  MATCH(authors.authorName) AGAINST('$q') as ascore,  MATCH(chapters.content) AGAINST('$q') as cscoreFROM 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's solution is great, however in my case I wanted to roll up the one-to-many results into a single row per search result. Riffing on @Ike Walker's solution here's how I got the job done:

Schema:

T1: ArticlesT2: Comments (many comments to one article)

Indexes:

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

Note: If you want to add weights to each field you could do something like.

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

In this case title would have 3x, body 2x the value of a match in comments.


It depends on what you want to sort by. You could sort by author, then title, then chapter content with this

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

the idea being that when you find the authors name, it's more relevant than when it's found in the title, which in turn is more relevant than finding it in the chapter text. You could also sort by the total relevancy with

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

but that might give odd results, as something where the search text only shows up in the chapter content could show up before the title.