いっぽんの猟銃のむこうに (DAIZOじいさんとGun)

ヌルめの技術メモとか。フリーランスやってます (http://acez.jp/)

Solr4.4で日本語検索する場合のschema.xmlフィールド設定メモ

毎回データ型っぽいやつを忘れるので。基本的にexampleのschema.xmlをベースに。

 <fields>
   <!-- 主キー -->
   <field name="id" type="string" indexed="true" stored="true" required="true" multiValued="false" />
    <!-- 完全一致 -->
   <field name="category" type="string" indexed="true" stored="true" required="true" multiValued="false" />
   <!-- Kuromojiによる形態素解析 -->
   <field name="title" type="text_ja" indexed="true" stored="true" />
   <!-- bigram(2-gram)による分かち書き -->
   <field name="caption" type="text_cjk" indexed="true" stored="true" />
   <!-- unigram(1-gram)による分かち書き (追加拡張) -->
   <field name="author" type="text_cjk_uni" indexed="true" stored="true" />
   <!-- 日付 -->
   <field name="regdt" type="date" indexed="true" stored="true" />
   <!-- タグ検索(完全一致、複数項目格納) -->
   <field name="tags" type="string" indexed="true" stored="true" multiValued="true" />
   <!-- コピーフィールド、全検索用のフィールド(unigram) -->
   <field name="text" type="text_cjk_uni" indexed="true" stored="false" multiValued="true"/>
   <!-- お約束  -->
   <field name="_version_" type="long" indexed="true" stored="true"/>
 </fields>

 <!-- UNIQ KEY(PK) -->
 <uniqueKey>id</uniqueKey>

  <!-- copyField -->
   <copyField source="title" dest="text"/>
   <copyField source="category" dest="text"/>
   <copyField source="caption" dest="text"/>
   <copyField source="author" dest="text"/>
   <copyField source="tags" dest="text"/>

(略)

    <!-- CJK bigram (see text_ja for a Japanese configuration using morphological analysis) -->
    <fieldType name="text_cjk" class="solr.TextField" positionIncrementGap="100">
          .....
    </fieldType>

    <!-- text_cjk unigram版(outputUnigrams="true") -->
    <fieldType name="text_cjk_uni" class="solr.TextField" positionIncrementGap="100">
      <analyzer>
        <tokenizer class="solr.StandardTokenizerFactory"/>
        <filter class="solr.CJKWidthFilterFactory"/>
        <filter class="solr.LowerCaseFilterFactory"/>
        <filter class="solr.CJKBigramFilterFactory" outputUnigrams="true"/>
      </analyzer>
    </fieldType>

(略)

こんな感じでスキーマ定義して、それぞれこんなデータを入れて検索してみます。

内容に意味はないです。

[
{
        "id" : "1",
                "title" : "きんいろモザイク",
                "category" : "アニメ",
                "caption" : "今季最高のクソかわアニメーション",
                "author" : "原悠衣" ,
                "regdt" : "2013-09-27T23:59:59Z",
                "tags" : ["金髪","アリス・カータレット","良さ", "まんがタイムきららMAX"]
}
,
{
        "id" : "2",
                "title" : "ご注文はうさぎですか?",
                "category" : "4コマ漫画",
                "caption" : "来世紀最高のクソかわコミックス",
                "author" : "Koi" ,
                "regdt" : "2012-02-27T23:59:59Z",
                "tags" : ["喫茶店","ティッピー","良さ", "まんがタイムKRコミックス"]
}
]

これを検索してみると、

  • "title"は形態素解析(Kuromoji)されてインデックスが作られる。
    • 「うさぎか?」と検索しても「ご注文はうさぎですか?」がヒットする
    • 「きんモザ」で検索して「きんいろモザイク」がヒットする(※1)
    • 「うさ」など、単語途中での検索はヒットしない。
  • "category"、"tags"は完全一致。
    • "category:漫画"とか"tags:まんがタイム"とか"tags:良い"はヒットしない。
    • "tags:良さ" で検索すると2件ともヒットする。
  • "caption"はbigram(2-gram)でインデックスが作られる。
    • "caption:高の" のように文章の途中でもヒットする。
    • 2-gramなので"caption:高"のように1文字だけでの検索はヒットしない。
  • "author"はunigram(1-gram)でインデックスが作られる。
    • "author:原"など1文字での検索もヒットする。
  • "text"は"title", "category", "caption", "author", "tags"を連結したインデックスが作られる
    • solrconfig.xmlのSearchHandlerでdefaultがtextと指定されているので、フィールド名を指定しない場合自動的にここから検索される。(前はschema.xmlのdefaultSchemaとかそんな感じで定義してた奴)
    • text_cjk_uni(1-gram)指定で作ってあるので、titleとかcategory, captionでは引っかからない条件でも拾える。
    • ただしインデックスサイズは最大になる。

とまあ、こんな感じ。

※1 tokenizerで"solr.JapaneseTokenizerFactory" mode="extended"を指定した場合。未知語とかに強くなるらしい。こんな略称検索がヒットするとは思わなかった。

Kuromojiの形態素解析とbigram, unigramあたりは一長一短なので、用途で使い分けるんですかね。


あとtomcatの場合

  • schema.xmlを更新したらtomcatは再起動してインデックス再作成(データ再投入)

を忘れずに。