4

アジア文字で埋められたレコード (中国語、日本語、韓国語) とラテン文字で埋められたレコード (英語、フランス語など) でいっぱいのデータベースがあり、それらの全文検索を実行したいと考えています。

MySQL は次のように述べています。

中国語や日本語などの表意文字言語には単語区切り文字がありません。したがって、FULLTEXT パーサーは、これらの言語やその他の言語の単語の開始位置と終了位置を判別できません。これの意味と問題のいくつかの回避策は、セクション11.8「全文検索機能」で説明されています。

セクション 11.8 では、実際には回避策が提供されておらず、問題についても言及されていません。

では、混合文字データベース内の単一の漢字の検索をどのようにソートしますか? %LIKE%動作しますが、気の利いた関連性評価はありません。キャラクターがレコードに登場する回数を数えて、それでランク付けするだけですか?アドバイスをいただければ幸いです。ありがとう!

4

1 に答える 1

2

データセットのサイズによって異なります。数十万行の場合は、利用可能な優れた独立した全文検索ソリューションの 1 つを検討するでしょう。実際、mysqlf でこの問題に対処する必要がなかったので、どのソリューションがアジア言語のサポートを含むのかわかりません。

ただし、luceneが中国語、日本語、韓国語のアナライザーを備えていることは知っているので、あなたがしていることを何らかの形でサポートしていると思います。lucene を php に統合する必要がある場合、私が通常行うことは、lucene をソケット サーバーとして実装し、php からそれに接続することです。

データセットが十分に小さい場合は、独自のアドホック アプローチを展開するオプションになる可能性があります。この問題には 2 つの部分があります。ランク付けするドキュメントの取得と、実際のランク付けです。回収にはいくつかの方法があります。データセットが十分に小さい場合は、LIKE を使用することもできます。もう 1 つの方法は、独自のディスク ベースのインデックス作成スキームを作成することですが、これはかなり複雑で時間がかかります。以下で説明するように、MySQL を中間パスとして使用することもできます。

MySQL を使用してインデックス作成スキームを実装するには、次の構造を持ついくつかのテーブルを作成する必要があります。

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)

次に、各ドキュメントを処理し、ドキュメント内の文字 (トークン) ごとに document_token テーブルに行を挿入します。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 がすべての選択にインデックスを利用できるようにするためのハックであり、単一の選択と複数の or ステートメントを使用する対応するクエリよりもおそらく高速です)

これにより、残りの問題として関連性ランキングが残ります。これは、あなたが本当に求めていたものです. :)これは、 Vector Space Model (VSM)を利用することで、かなり良い結果を得ることができます。

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

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 として保存します。これで、コサイン類似度を使用してこのドキュメントのスコアを計算できます。

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

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

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

于 2009-05-03T15:53:49.617 に答える