2009-05-03 8 views
4

アラビア語のレコード(中国語、日本語、韓国語)とラテン文字のレコード(英語、フランス語、あなたの名前)を含むデータベースがあります。それらの全文検索を実行したいMySQL全文表意文字(アジア系)の検索

MySQLは言う:中国語 や日本など

表意言語は単語 区切り文字を持っていません。したがって、FULLTEXT パーサは、 の開始と終了を、これらの言語と他のそのような 言語でどこで判別できません。この の影響と問題 のいくつかの回避策については、11.8、 「全文検索機能」で説明しています。

第11.8節では、実際には回避策が提供されておらず、問題点についても言及していません。

だから、混在文字データベースの検索でどのように1つの中国語文字を並べ替えるのですか%LIKE%はうまくいくが、関連性の点で気にならない。キャラクターがレコードに登場する時間を数えてそれをランク付けすればよいのですか?あなたのアドバイスに感謝します。ありがとう!

答えて

2

データセットのサイズによって異なります。私たちが何十万行もの行を話しているなら、おそらく、利用可能な優れた独立した全文検索ソリューションの1つを見てみよう。私は実際にこの問題をmysqlfに対処する必要がなかったので、アジア言語のサポートを含むどのソリューションがわからないのです。

しかし、luceneは、中国、日本、韓国のアナライザーを使っていることがわかります。私の推測では、あなたのやりたいことに対するサポートがあります。 luceneをPHPに統合する必要があるときに私が通常行うことは、luceneをソケットサーバーとして実装し、PHPから接続することです。

データセットが十分小さい場合は、独自のアドホックアプローチを使用することもできます。この問題には2つの要素があります。ランク付けするドキュメントの取得と実際のランキングです。検索を行うにはいくつかの方法があります。データセットが十分に小さい場合は、LIKEを使用することがあります。もう1つは、ディスクベースのインデックス作成方式を使用することですが、これはかなり複雑で時間がかかります。後述のように、MySQLを中間パスとして使用することもできます。その後、私は、各文書を処理し、ためdocument_tokenテーブルに行を挿入したい

document 
    document_id 
    document_text 
    document_tokencount 

document_token 
    document_id 
    token_id 
    token_docfrequency 
    index (token_id, document_id) 

token 
    token_id 
    token_unicode 
    token_globalfrequency 
    index (token_unicode) 

MySQLを使用してインデックス方式を実施するためには、次のような構造を持ついくつかのテーブルを作成する必要があります文書内の各文字(トークン)。 token_unicodeフィールドには、この文字を参照するために使用される整数のUnicodeシーケンスが含まれます。 token_docfrequencyフィールドは、文書がトークンを含む回数に対応する整数を含み、token_globalfrequencyフィールドは、用語が使用された総回数をすべての文書にわたって含む。

これは、あなたがトークンの迅速な検索を行うことができるようになる:

SELECT * FROM document_token WHERE token_id = 1 
UNION 
SELECT * FROM document_token WHERE token_id = 2 
UNION 
SELECT * FROM document_token WHERE token_id = 3 

(労働組合のアプローチは、mysqlはすべての選択のためのインデックスを利用することを可能にするハックであり、最も可能性の高い対応するクエリよりも高速になります

これは、あなたが本当に求めている残りの問題として関連性のランク付けをしてくれます。 :)これは、Vector Space Model (VSM)を利用するとかなり良い結果が得られます。

最初に行う必要があるのは、このトークンのスコア​​を計算することです。これは、次の式を使用して行われます。

tf-idf = tf(t,d)/tf(d) * log(D/d(t)) 

where: 
tf(t,d) = token frequency in current document 
tf(d) = total number of tokens in current document 
D = total number of documents 
d(t) = number of document that contains the token 

検索クエリの各用語についてこのスコアを最初に計算し、その結果をハッシュマップまたは類似のものに格納します。これがv_1という最初のベクトルです。次に、最初の文書に進みます。ドキュメント内の各用語のtf-idfスコアも計算し、それをv_2として保存します。今、あなたはcosine similiarityを使用して、この文書のスコアを計算することができます

score = arccos(v_1 * v_2/(|v_1| * |v_2|)) 

結果は文書をランク付けするために使用される値です。続行し、すべての文書でこれを実行します。それらを降順で並べ替えます。リストの最初の文書が最も関連性の高い文書になります。

これは少し複雑に思えるかもしれませんが、線形代数の基本的な知識があれば、おそらく数時間で実用的な解決策を生み出すことができます。それでも可能であれば、luceneなどの既存のソリューションを使用してください。