Apache Solrのデモ環境を作ってみる | A Day In The Boy's Life

A Day In The Boy's Life

とあるエンジニアのとある1日のつぶやき。

前回の「Apache Solrを利用して本格的な検索エンジンを導入する 」の続き。

前回のエントリでApache Solr4.2のインストールと日本語検索の環境設定を行いましたが、今回は具体的なApache Solrの操作感をまとめていきたいと思います。



Apache Solrのデモ環境を作る


何にせよやっぱり動く環境を見ていくのが一番理解しやすいわけですが、デモサイトを一から用意してとなると結構手間になることから、下記のサイトの情報をベースに書いていきます。


第5回 全文検索エンジン「Lucene/Solr」を導入する @ ITpro


この記事はApache Solr1.3系の古いバージョンでの解説記事なので、このエントリではそれを4系のバージョンに焼きなおしたようなものになっています。


まず、P.1のSolrのインストールや環境準備は前回のエントリで整っているので割愛します。

ということで、P.2以降(要会員登録)のところからですが、簡易的な住所検索のプログラムのソースが一式ダウンロードできますので落としておきます。

このデモは、このアプリを使ってApache Solr上で住所検索をするというものです。

適宜、上記のITproのサイトも参照しながら読んでみてください。


住所検索プログラム(html、js、xslファイル)は、サーバー上にアップロード後、Apache Solrの公開ディレクトリに展開します。

便宜上、ディレクトリ名はデフォルトのCustomModulesからsearchという名前に変更しています。


$ cd /path/to/solr/example/solr-webapp/webapp/
$ cp ~/CustomModules.zip ./
$ unzip CustomModules.zip
$ mv CustomModules search
$ cd search
$ mkdir js
$ cd js
$ mv ../prototype-1.6.0.3.js ./

最後にしている作業は、prototype.jsファイルの呼び出し方がjsディレクトリにあるものを読込むようになっているため、ファイルを移動させています。

次に、Apache Solrの定義ファイル(schema.xml)をSolrのconfディレクトリに展開します。


$ cd /path/to/solr/example/solr/collection1/conf/
$ mv /path/to/solr/example/solr-webapp/webapp/search/schema.xml ./

ちなみに、collection1というのはSolrの検索エンジンのコアディレクトリになっており、コアごとに設定ファイルやデータファイルが存在します。


これで準備完了ということで住所録をSolrにインポートさせたいところですが、Apache Solr4系から幾つか仕様が変わっているめこのままだとエラーが出てうまくいきません。

そのため、先ほど展開したschema.xmlファイルを編集します。


<!--
<filter class="solr.EnglishPorterFilterFactory" protected="protwords.txt" />
-->

上記を編集しなかった場合、Solrを起動したときに下記のようなエラーが発生します。


collection1: org.apache.solr.common.SolrException:org.apache.solr.common.SolrException: Plugin init failure for [schema.xml] fieldType "textTight": Plugin init failure for [schema.xml] analyzer/filter: Error loading class 'solr.EnglishPorterFilterFactory' 

Apache Solrではデータのインポートや検索のときに幾つかフィルタを通すことができます。

フィルタを通すことでデータを加工したり(例えば大文字を小文字にしたり、日本語の場合は形態素解析エンジンを指定したり、インデックスしないキーワードを指定したりなど)しながら利用できます。

そのフィルタが存在しないためのエラーなのですが、フィルタを使わなくても利用可能なためコメントアウトしてしまいます。


次に、fieldsタグの最後(93行目あたりの</fields>の直前)に、下記の項目を追加します。


<field name="_version_" type="long" indexed="true" stored="true"/>

これも登録しておかないと下記のようなエラーが出てしまいます。


collection1: org.apache.solr.common.SolrException:org.apache.solr.common.SolrException: Unable to use updateLog: _version_field must exist in schema, using indexed="true" stored="true" and multiValued="false" (_version_ does not exist) 

私は、Solr4系からしか触っていないのですが、どうも4系から_version_というフィールドが必須となっているようです。


これで、schema.xmlファイルの編集は完了です。

schema.xmlの詳解は「Apache Solrのschema.xmlを読み解く 」にもまとめていますので参考にしてみてください。


もし、Solrを起動している場合は再起動しておきます。

前回のエントリで書いたように児童起動スクリプトを用意している場合は、


# /etc/init.d/solr restart

のようにしておきます。



Apache Solrへデータをインポートする


これでようやくSolrに住所録データを登録できるので、サーバーに展開したディレクトリに含まれるzip-code.xmlをSolrに取り込みます。


$ cd /path/to/solr/example/exampledocs
$ ./post.sh zip-code.xml
Posting file zip-code.xml to http://localhost:8983/solr/update

<?xml version="1.0" encoding="UTF-8"?>
<response>
<lst name="responseHeader"><int name="status">0</int><int name="QTime">21506</int></lst>
</response>
<?xml version="1.0" encoding="UTF-8"?>
<response>
<lst name="responseHeader"><int name="status">0</int><int name="QTime">352</int></lst>
</response>

post.shは、Solrに付属しているSolrと対話するためのシェルスクリプトです。

Solrとの対話はRESTなAPIを通して行います。

post.shのシンプルなシェルスクリプトの中身を見ればわかりますが、実質


curl $URL --data-binary @$f -H 'Content-type:application/xml'

という一行だけで、このようにHTTPを通してSolrにデータの取り込みや検索など様々な実効命令が行えます。

要はHTTPクライアントとして動作する環境があればよいので、その他のプログラムからも簡易的に対話プログラムを書く事ができます。


もし、住所録データの取り込みがうまくいかない場合は、zip-code.xmlの文字コード周りかもしれません。

私の場合、サーバー環境がEUC-JPだったため少してこずったりしました。

zip-code.xmlをEUCで保存して、iconvなどからUTF-8に変換しなおして取り込んだらうまくいったりしました。


ここまでうまくいったら一旦、Solrの管理サイトから検索を実行してみましょう。

Solr管理サイトにアクセスし、左下のリストボックスから「collection1」を選択し、Queryメニューを開きます。

そこで、何も入力・変更しない状態で下のほうにある「Execute Query」ボタンをクリックして結果が表示されればうまく取り込まれています。


A Day In The Boy&#39;s Life-ApacheSolrで検索


データの取り込みと管理サイト上での検索がうまくいったらデモ環境の構築に戻りましょう。


http://localhost:8983/solr/search/search.html


へアクセスしてみます。

これで、ITproの記事で解説されているように住所検索システムへアクセスできます。


A Day In The Boy&#39;s Life-ApacheSolrデモサイト


しかし、最初のテキストボックスに例えば都道府県名を入力して検索しても何も反応がありません。

先ほど検索してみた、Solrの管理サイトのQueryメニューから「q」と書かれたテキストエリアに都道府県名を入力してみても同様にヒットしません。


<?xml version="1.0" encoding="UTF-8"?>
<response>

<lst name="responseHeader">
  <int name="status">400</int>
  <int name="QTime">1</int>
  <lst name="params">
    <str name="indent">true</str>
    <str name="q">北海道</str>
    <str name="_">1368198319211</str>
    <str name="wt">xml</str>
  </lst>
</lst>
<lst name="error">
  <str name="msg">undefined field text</str>
  <int name="code">400</int>
</lst>
</response>


この理由は、キーワードの検索対象フィールドが設定ファイル内で定義されているためです。

試しに検索キーワードに「prefecture:北海道」と入力して検索してみるとヒットするはずです。

これは、prefectureフィールドに対して検索しろって指定になります。
エラーメッセージにあるようにデフォルトでは、textという名前のフィールドに対して検索をしており、そのようなフィールドは取り込んだデータの中では存在していないためエラーを返してきます。

ということで、Solrの設定ファイル(solrconfig.xml)を編集します。


$ cd /path/to/solr/example/solr/collection1/conf/
$ vi solrconfig.xml

この中で、774行目あたりに検索実施時のデフォルトで検索するフィールド(dfという名前のフィールド)が定義されていますので、コメントアウトしてしまいます。


  <requestHandler name="/select" class="solr.SearchHandler">
    <!-- default values for query parameters can be specified, these
         will be overridden by parameters in the request
      -->
     <lst name="defaults">
       <str name="echoParams">explicit</str>
       <int name="rows">10</int>
       <!-- <str name="df">text</str> -->
     </lst>


編集が完了したらSolrの再起動が必要です。


これで再度、都道府県名だけで検索してみると結果が表示されるはずです。


A Day In The Boy&#39;s Life-ApacheSolrデモサイトでの検索結果


ということで、デモサイトが出来上がったのでSolrの検索の最初の最初に触れる環境が整いました。

具体的な使い方を書きたいところですが、エントリも長くなったのでまた次回に。