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. 無料アクセス解析
スポンサーサイト
2009-02-18(Wed)

solr qeury parameter (問合せの記述)

なんで、Solr の GETパラメータを日本語で解説しているサイトがないのか!?
速度の比較記事やインストールしたがうまくいかないとか、そんなばっかです。

Solr Wikiは簡単な英語で書かれているのでわかる事はわかるんだけどね。
「何が出来ないのか」ってのがよくわからんかったよ。


とりあえず、よく使うであろうパラメータを箇条書き

1.問合せURL
http://192.168.1.1:8983/solr/select/?検索パラメータを繋げる

2.問合せパラメータ
「q=条件」は必須です。
問合せはクエリー「q=検索条件」で行う方法と、フィルタ「fq=検索条件」で行う方法があります。
フィルタの方が検索スピードは速くなります。
XX_IDといったキー項目だけではなく、単価などで範囲を指定する事もできます。

例1.なんたらIDで検索を行なう場合
foo_id:1001

例2.単価を範囲指定
tanka:[5000 TO 10000]

例3.日付の範囲指定
yukodate:[2009\-02\-01T00\:00\:00Z TO 2009\-02\-28T23\:59\:59Z]

solrの日付フォーマットは「YYYY-MM-DDT00:00:00Z」です。
日付と時刻の間に「T」を、時刻の後ろに「Z」が必ず必要です。

上記の例ではphpでurlencode()をするときに「-」や「:」がデコードされないように
「\」を入れています。

検索パラメータの書式は「q」パラメータ、「fq」パラメータ共通です。

複数の条件を指定する場合は「 AND 」や「 OR 」で条件を結合します。
また、「(」「)」も使用できます。
fq=cate_id:1001 AND tanka:[5000 TO 10000]


※注意事項
① solrではGETパラメータの半角空白は区切り文字として扱われるので、
phpの場合、urlencode()を使用して「+」に変換します。
javaもurlencode()でOK。
但し、範囲指定の場合は「[」「]」がありurlencode()出来ないので
直接「tanka:[5000+TO+10000]」と記述しています。

ASPの場合、Server.UrlEncodeしても半角空白を「+」に変換してくれないので
自前で変換する必要があります。

② solrでは「q」パラメータは必須となっています。
検索条件がフィルタだけで済む場合でも「q」パラメータを指定しないといけないので
下記のように記述します。
「q=*:*」
「*:*」は全件という意味です。


3.並び替えパラメータ
並び替えパラメータは「sort=フィールド名」です。
昇順/降順の指定は「フィールド名 asc|desc」と記述します。

複数のフィールドを使用する場合、カンマ区切りで列挙します。

例)sort=ins_date desc,foo_id asc

ここでも半角空白をsolrへGETパラメートして渡せないので、urlencode()を行ないます。
実際のURL記述は「sort=ins_date+desc%2Cfoo_id+asc」のようになります。


4.グループ集計パラメータ
グルーピングして、グループ毎の抽出件数を取るには「facet」パラメータを記述します。

facetパラメータを使用する際に同時に指定するパラメータがいくつかあります。

facet=true|false
facetした結果を出力するか、しないかを指定

facet.sort=true|false
true:facetした結果件数を件数の多い順に並び替えを行ないます。
false:アルファベット順に並び替えするらしいです。(使ったこと無いです)

facet.mincount=n
集計した結果、n件以上の結果だけを返します。デフォルトは0です。

facet.limit=n
集計結果を返す件数を指定します。デフォルトは100です。

facet.field
集計を行うフィールドを指定します。
複数のフィールドを指定する場合、「facet.field=」を複数記述します。
例)facet.field=foo_id&facet.field=city_cd

facet.offset
集計結果を何個目から返すかを指定します。デフォルトは0です。


上記以外にもfasetのパラメータがあります。
facetパラメータ

5.検索結果を返し始める行の指定
「start」パラメータを記述します。
検索結果の11件目から返す場合、「start=10」と記述します。


6.検索結果を返す数の指定
「rows」パラメータを指定します。
20件だけ検索結果を取得したい場合は「rows=20」と記述します。

 5と6は一覧ページで表示件数を制御する際に使えますね。

7.取得フィールドの指定
「fl」パラメータで指定します。
複数のフィールドを指定する場合はフィールドをカンマ区切りで指定します。

以上。
  1. 無料アクセス解析
プロフィール

lidelu

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

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

この人とブロともになる

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