FC2ブログ
--------(--)

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。
2009-02-18(Wed)

solr schema.xml (1文字の日本語検索が CJKAnalyzer では駄目だった)

CJKAnalizerでは「花」の1文字の検索を行うと、検索出来ない不具合が見つかった。
その他に検索できない日本語が色々出てきたので、CJKAnalizerには身を引いてもらいます。

んで、色々試したのですがどれも一長一短すぎ、使い物にならないので、
N-Gramを使用することにしました。

N-Gram を 1-gram で使用した場合、語句に関係無く文字が一致するとヒットしてしまうので、検索ワードが2文字以上の場合は 2-gram を使用する方針としました。

データ上に検索キーワードが存在するのに CJKAnalizer ではヒットしない場合があるなんて、信じられない!。

solrを使用している事例は日本語のページでも見ますが、こういう事が明らかにされていないのは非常に不親切ではないでしょか??
実際solrの問い合わせパラメータを日本語で説明しているサイトも無いし、オープンソースなんだから、Solrをお勧めしてるサイトはこういうノウハウ(不具合)も表明しないと日本で使ってくれないじゃない?


定義ファイル
~solr/conf/schema.xml


定義内容


<field name="syo_id" type="slong" indexed="true" stored="true" required="true"/>
<field name="buyer_id" type="slong" indexed="true" stored="true"/>
<field name="syo_name" type="text" indexed="true" stored="true"/>
<field name="tanka" type="slong" indexed="true" stored="true"/>
<field name="yukodate" type="date" indexed="true" stored="true"/>


indexed="true"
 並び替え、フィルターといった検索時の条件で使われる
 メモリを消費する
indexed="false"
 検索時の条件としては使われない

stored="true"
 結果データとして返される
 ディスク領域を消費する
stored="false"
 結果データとして返す必要がない



日本語検索
初期設定ではCJKAnalizerを使用していますが、検索文字(日本語)によっては検索できない場合があったのでNGramを使用するようになりました。

↓の定義をschema.xmlに追加。


<fieldtype name="unigram_type" class="solr.TextField">
<analyzer>
<tokenizer class="solr.NGramTokenizerFactory" maxGramSize="1" minGramSize="1" />
<filter class="solr.LowerCaseFilterFactory"/>
</analyzer>
</fieldtype>


<fieldType name="bigram_type" class="solr.TextField">
<analyzer>
<tokenizer class="solr.NGramTokenizerFactory" maxGramSize="2" minGramSize="2" />
<filter class="solr.LowerCaseFilterFactory"/>
</analyzer>
</fieldType>




検索語が1文字のときは "q=text:検索文字" でなく"q=unigram:検索文字" を投げます。

uniram_typeは1-gramでインデックスするフィールドです。
上記の定義を見てわかると思いますが、
「maxGramSize="1" minGramSize="1"」
としているので、1文字ずつインデックスしています。

bigram_typeは2-gramでインデックスするフィールドです。
「maxGramSize="2" minGramSize="2"」
としているので、2文字ずつインデックスしています。

で、schema.xmlにunigram_typeのフィールドとbigram_typeのフィールドを定義します。


<field name="uigram" type="unigram_type" indexed="true" stored="false" multiValued="true"/>
<field name="biggam" type="bigram_type" indexed="true" stored="false" multiValued="true"/>



本来のフィールドはそのままの定義で、copyFieldを設定してunigramフィールドとbigramフィールドにコピーするよう設定します。
これを行なうことで source で定義したフィールドが dest で定義したフィールドに内部でコピーされます。
「multiValued="true"」としているのは、unigramフィールドとbigramフィールドに複数のフィールド項目をコピーさせるからです。

このときunigramフィールドとbigramフィールドはNGramTokenizerFactoryで解析するように定義しているので N-gramでインデックスが作成されます。

以上。
  1. 無料アクセス解析
関連記事
スポンサーサイト

comment form

管理者にだけメッセージを送る

comment

プロフィール

lidelu

Author:lidelu
FC2ブログへようこそ!

最近の記事
最近のコメント
最近のトラックバック
月別アーカイブ
カテゴリー
ブロとも申請フォーム

この人とブロともになる

ブログ内検索
RSSフィード
リンク
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。