Apache Solrを利用して本格的な検索エンジンを導入する | A Day In The Boy's Life

A Day In The Boy's Life

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

情報を検索するというのは、どんなサービスであれ重要な機能になってきますが、単純なDB検索などでは情報の精度が悪かったり、パフォーマンスが出ないといった問題が出てきます。

SQLのLIKE文ではIndexが使われなかったり、あいまい検索をすると余計な情報が引っかかったりして、その検索順位のスコア付けをしようとすると別のロジックが必要になってきたりして、かなり複雑な処理になってきます。


そんなこんなで億劫になってしまう検索システムですが、Apache Solr を利用すると手軽に高度な検索システムを導入することができます。



Apache Solrをインストールする


Apache SolrはJavaで書かれているため、利用するためにはJava(バージョン1.5以上)の環境を用意する必要があります。

今回の環境では、CentOS6.4にApache Solr4.2をインストールします。


Javaの環境が用意されていない場合は、yum経由とかでインストールしておきましょう。


# yum install java-1.6.0-openjdk.x86_64
# yum install java-1.6.0-openjdk-devel.x86_64
# yum install ant.x86_64

antは、後で説明する形態素解析用エンジンであるSenを利用する際に必要になってきますのであわせて準備しておきます。


Javaの環境が整ったら、Apache Solrのソースファイルをダウンロード します。

ファイルのダウンロードが終わったらサーバーにアップロードし、適当なディレクトリに展開します。


最もシンプルに使う方法としては、インストールはたったこれだけで完了です。

試しにApache Solrを起動してみます。

起動用のjarファイルがexampleディレクトリ内にあります。


# cd /path/to/solr/example/
# java -jar start.jar >> /var/log/solr.log 2>&1 &

これで起動完了です。

エラーがある場合は、ログに書き出されるので確認してみましょう。

ちなみに、デフォルト設定だとApache Solrは8983ポートを使います

iptablesの設定をしている場合は、そのポートを解除しておきましょう。


起動ができたら、管理サイトにアクセスしてみましょう。


http://localhost:8983/solr/#/


下記のような管理サイトが表示されたらインストール成功です。


A Day In The Boy's Life-ApacheSolr管理サイト


ちなみに、このインストール方法はSolrに内蔵されているJettyを利用しているため、既存環境にApacheが動いていても平行稼動ができます。

利用する際のポート番号を変えたい場合は、下記Jetty用のファイルを編集しましょう。


/path/to/solr/example/etc/jetty.xml

最後に、毎回start.jarファイルをたたくのも面倒なので、自動起動用スクリプトを作って/etc/init.d(と、ランレベルに応じてrc3.dとか)に配置しておきます。


#!/bin/sh
# chkconfig: 345 90 90
# description: Solr Boot
JETTY_HOME_DIR=/path/to/solr/example/
cd $JETTY_HOME_DIR
JAVA="/usr/bin/java"
LOG_FILE="/var/log/solr.log"

KEY=stopkey
CORE=solr
cd $JETTY_HOME_DIR
start() {
  $JAVA -Dsolr.solr.home=$CORE -DSTOP.PORT=8079 -DSTOP.KEY=$KEY -jar start.jar >> $LOG_FILE 2>&1 &
  echo "Solr started!"
}

stop() {
  $JAVA -DSTOP.PORT=8079 -DSTOP.KEY=$KEY -jar start.jar --stop
  echo "Solr stopped!"
}

case "$1" in
    start)
        start
        ;;
    stop)
        stop
        ;;
    restart)
      stop
      start
      ;;
    *)
      echo "Usage: $0 {start|stop|restart}"
      exit 1
esac


chkconfigとかはお好みでどうぞ。



形態素解析エンジンSenをインストール


ここまでの作業でSolrは利用可能になっていますが、データに日本語が入っている場合は検索できません。

英文と違って日本語は単語の区切りがわかりづらいので、形態素解析を使って文章内のキーワードを抽出する仕組みが必要になってきます。

Senは形態素解析エンジンのMeCabをJava用のライブラリとして移植したものです。


Senのソースファイルのダウンロードはブラウザ経由でできないため、SVN経由で落としてきます。


$ svn co https://svn.java.net/svn/sen~svn/tags/SEN_1_2_2_1/sen
$ cd sen
$ ant


「BUILD SUCCESSFUL」というメッセージが最後に表示されたら完了です。

Senのビルドが終わったら形態素解析の元データとなる辞書登録を行います。

今回はIPAdic legacy を使います(バージョン2.7)。

上記のサイトから辞書データのtarボールをダウンロードしてサーバーにアップしておきます。


元々、Sen自体の辞書登録スクリプト(ビルド用ファイル)がIPAdicを使うようになっているのですが、Senのバージョン1.2.2.1ではこの辞書登録用のスクリプトが古くそのままだと動かないので編集します。


$ cd /path/to/sen/dic

上記フォルダ内にある、build.xmlを編集します。

まずは、17行目あたりにあるバージョン情報を「2.6.0」から「2.7.0」に変更。


<property name="ipadic.version" value="2.7.0"/>

次に、このビルド用のファイルはサーバーから直接ファイルをダウンロードして辞書登録する仕組みになっていますが、そのパスに現在はファイルが存在しません。

そして、先ほど辞書データをダウンロードしてサーバーにアップしているのでそちらを利用してもらうように編集します。

具体的には、サーバーから直接取りにいく処理をコメントアウトしてしまいます(64行目あたり)。


  <target name="download" depends="prepare-proxy,prepare-archive,prepare-dics0,prepare-dics" unless="ipadic.archive.present">
<!--
    for proxy
    <setproxy socksproxyhost="proxyhost" proxyport="8080" />
    <get src="${ipadic.home}/${ipadic.archive}" dest="${ipadic.archive}" />
-->
  </target>
  <target name="melt" depends="download,prepare-dics" unless="dics1.present">
<!--
    <gunzip src="${ipadic.archive}"/>
    <untar src="${ipadic.dir}.tar" dest="." />
    <delete file="${ipadic.dir}.tar"/>
-->
  </target>


そして、先ほどアップしておいた辞書データをSenの辞書データ保管用のディレクトリに移動させます。


$ cd /path/to/sen/dic
$ cp -R /path/to/ipadic-2.7.0 ./
$ ant


こちらも最後に「BUILD SUCCESSFUL」というメッセージが出てきたらビルド完了です。
最後に、出来上がった辞書用のライブラリをSolrに組み込みます。


$ cd /path/to/sen/lib
$ cp sen.jar /path/to/solr/example/solr-webapp/webapp/WEB-INF/lib/

この一連の作業で、Apache Solrで形態素解析が利用できるようになります。


以下、余談ですがSenのインストール時にエラーが出た場合の対処です。

まず、Senをantでビルドする際に文字コードに関するWarningが出たりします。


compile:
    [javac] Compiling 31 source files to /path/to/sen/build/classes
    [javac] /path/to/sen/src/java/net/java/sen/SenUtils.java:158: warning: unmappable character for encoding euc_jp

が、これは基本的にメッセージなので無視してかまいません。

そして、個人的にはまったのが


[javac] /path/to/sen/src/java/net/java/sen/util/DoubleArrayTrie.java:1: class or interface expected
    [javac] cpp: error trying to exec 'cc1plus': execvp: No such file or directory
    [javac] ^
    [javac] /path/to/sen/src/java/net/java/sen/util/DoubleArrayTrie.java:1: unclosed character literal
    [javac] cpp: error trying to exec 'cc1plus': execvp: No such file or directory
    [javac]                           ^
    [javac] /path/to/sen/src/java/net/java/sen/util/DoubleArrayTrie.java:1: unclosed character literal
    [javac] cpp: error trying to exec 'cc1plus': execvp: No such file or directory

というエラーで、結論から言うとJavaやantの環境ではなく、gccやgcc-c++パッケージが入っていなかったために起きるという問題でしたので、yum経由でパッケージをインストールしたらantのビルドがうまくいきました。


そして、Solrの具体的な使い方の話を書いていきたいのですが、記事が結構長くなってしまったので、また次回にまとめていきたいと思います。