2012-01-26 19 views
11

私はサイト全体の検索機能の作成を担当しています。検索は記事、イベント、ページの内容を調べる必要があります複数テーブルにわたるMysql全文検索の関連性

私は以前にMySQLでMATCH()/ AGAINST()を使用しましたが、結果の関連性を得る方法を知っていますが、関連性が一意である限り検索(コンテンツ、行数など)に記事テーブルからの結果の関連性は、イベントテーブルからの結果の関連性と一致しません。

3つのテーブルすべての結果が妥当性を持つように関連性を統一する方法はありますか?

+0

これは論理的には、これを組み合わせて使用​​するのに適しているようです。私はこの方法で検索することは一度もありませんでした。私はこれが最良の方法だとは思わない。 – xQbert

+0

関連性を重み付けする方法はありますか?単なる単純な乗算 – bowlerae

+0

1との関連性を正規化することについては疑問を抱いていましたが、結果は複数のテーブルにまたがって返されます – michael

答えて

20

はい、Apache LuceneやSolrなどの検索エンジンを使用して、それらを非常にうまく統合できます。

http://lucene.apache.org/solr/

あなたが唯一のMySQLでそれを行う必要がある場合は、UNIONでこれを行うことができます。おそらくゼロ関連の結果を抑制したいと思うでしょう。

どのテーブルが一致するかによって、関連性にどのように影響を与えるかを決定する必要があります。

たとえば、記事が最も重要で、イベントが中程度に重要で、ページが最も重要でないようにするとします。あなたは、このような乗算器を使用することができます:ここで

set @articles_multiplier=3; 
set @events_multiplier=2; 
set @pages_multiplier=1; 

は、あなたがそれを試すことができます作業例ですこれらの技術のいくつかを示しています

は、サンプルデータを作成します。

create database d; 
use d; 

create table articles (id int primary key, content text) ENGINE = MYISAM; 
create table events (id int primary key, content text) ENGINE = MYISAM; 
create table pages (id int primary key, content text) ENGINE = MYISAM; 

insert into articles values 
(1, "Lorem ipsum dolor sit amet"), 
(2, "consectetur adipisicing elit"), 
(3, "sed do eiusmod tempor incididunt"); 

insert into events values 
(1, "Ut enim ad minim veniam"), 
(2, "quis nostrud exercitation ullamco"), 
(3, "laboris nisi ut aliquip"); 

insert into pages values 
(1, "Duis aute irure dolor in reprehenderit"), 
(2, "in voluptate velit esse cillum"), 
(3, "dolore eu fugiat nulla pariatur."); 

は、それが検索してください:

ALTER TABLE articles ADD FULLTEXT(content); 
ALTER TABLE events ADD FULLTEXT(content); 
ALTER TABLE pages ADD FULLTEXT(content); 

これらのテーブルをすべて検索するには、UNIONを使用してください。

set @target='dolor'; 

SELECT * from (
    SELECT 
    'articles' as 'table_name', id, 
    @articles_multiplier * (MATCH(content) AGAINST (@target)) as relevance 
    from articles 
    UNION 
    SELECT 
    'events' as 'table_name', 
    id, 
    @events_multiplier * (MATCH(content) AGAINST (@target)) as relevance 
    from events 
    UNION 
    SELECT 
    'pages' as 'table_name', 
    id, 
    @pages_multiplier * (MATCH(content) AGAINST (@target)) as relevance 
    from pages 
) 
as sitewide WHERE relevance > 0; 

結果:

+------------+----+------------------+ 
| table_name | id | relevance  | 
+------------+----+------------------+ 
| articles | 1 | 1.98799377679825 | 
| pages  | 3 | 0.65545331108093 | 
+------------+----+------------------+ 
+0

これは素晴らしいです!私は非常によく似た質問がありますが、私は関連するマッチが必要です。あなたもそれを見てみることができますか? http://stackoverflow.com/q/9953922/633513 – LordZardeck

+0

あなたは素晴らしいです! – Cogicero

+0

お返事ありがとうございます!!!! – Marcky

2

(申し訳ありませんが、私は上記の答えにコメントとしてこれを残しておきたいが、私はコメントするのに十分な評判を持っていけない)

サブクエリでUNIONことに注意してください非常に最適化されていません。よくあるケースは親クエリの "LIMIT @page * 10,10"を使用して結果を改ページしたい場合、MySQLはallの結果を親クエリを評価するために取得する必要があります。

関連する問題