2010-11-19 17 views
15

私は、3つの別々のテーブルでフルテキスト検索を行い、関連性によって結果を並べ替えることを試みています。答えを探しているうちに、私は複数の表で全文検索を使うことができないことを知りました。だから私は検索したい各列のための別個のフルテキストインデックスを追加しました。今問題は、私は検索を行うことができますが、私はソートを行うことができないようにしたいと思います。ここで複数テーブルの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 

ここでは、タイトル、著者または内容で並べ替えることができます。私がしたいのは、すべての3つの列の関連性を取得し、その結果を順序付けることです。

私はluceneやsphinxのような他の検索エンジンを知っていますが、今は使用する予定はありません。

ありがとうございます。

答えて

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

+0

私が助けてくれました。ありがとう! – youngcouple10

+1

非常にいいです、私は私のプロジェクトに必要なもの! – NaturalBornCamper

-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

私はそれを試してみました....あなたはORDER BY MATCH(..)AGAINST()を実行して、2番目のクエリ – ITECH

0

@Ikeウォーカーのソリューションは素晴らしいです、しかし、私の場合、私は、検索結果ごとに単一の行に1対多の結果をロールアップしたかったです。ここ@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 

この場合、タイトルはコメントの一致の値の2倍の3倍です。

関連する問題