Dovecot と Apache Solr で受信したメールを全文検索 ― 2013年01月04日
はじめに
みんな大好き Gmail は検索機能が強力であり、これが理由で Gmail を使っている人も少なくないと思います。しかし、家訓などで Gmail を禁止されている人もいることでしょう。たとえば、自前サーバーに Dovecot をインストールして使っているとか。しかし、Dovecot 標準のままだと検索がちょっと悲しいので、ちょっとだけ強くしてみます。
Dovecot はプラグイン機能で機能強化できますが、そのうちの一つ、fts (Full Text Search indexing) というプラグインを使うと、全文検索が強まります。fts はインデクサとしていくつかのプログラムを選択できますが、ここでは fts_solr 経由で、Apache Solr を使ってみることにします。なお、環境は Ubuntu Precise (12.04.1 LTS) です。
Solr をインストール
まず、Solr をインストールします。Solr は Ubuntu では Tomcat 版と Jetty 版が用意されていますが、ここでは Jetty 版をインストールします。
% sudo apt-get --install-suggests=no --no-install-recommends install openjdk-7-jre-headless openjdk-7-jdk solr-jetty
/etc/default/jetty
に手を入れて、Jetty を設定します。
--- a/default/jetty +++ b/default/jetty @@ -1,7 +1,7 @@ # Defaults for jetty see /etc/init.d/jetty for more # change to 0 to allow Jetty to start -NO_START=1 +NO_START=0 # change to 'no' or uncomment to use the default setting in /etc/default/rcS VERBOSE=yes @@ -13,10 +13,10 @@ VERBOSE=yes # Listen to connections from this network host # Use 0.0.0.0 as host to accept all connections. # Uncomment to restrict access to localhost -#JETTY_HOST=$(uname -n) +JETTY_HOST=localhost # The network port used by Jetty -#JETTY_PORT=8080 +JETTY_PORT=8080 # Timeout in seconds for the shutdown of all webapps #JETTY_SHUTDOWN=30 @@ -28,7 +28,7 @@ VERBOSE=yes #JAVA_OPTIONS="-Xmx256m -Djava.awt.headless=true" # Home of Java installation. -#JAVA_HOME= +JAVA_HOME=/usr/lib/jvm/java-7-openjdk-amd64 # The first existing directory is used for JAVA_HOME (if JAVA_HOME is not # defined in /etc/default/jetty). Should contain a list of space separated dire ctories.
これによって、以下のような設定で Jetty が起動するようになります。
- サーバーマシン起動時に Jetty を起動
localhost
の8080
番ポートを listen する。Dovecot は HTTP を使って、Solr のサーバーと通信しますが、このようにすることで、http://localhost:8080/solr/ のみで Solr にアクセスできるようになります (※1)/usr/lib/jvm/java-7-openjdk-amd64
の Java を使う
fts_solr プラグインのインストール
次に、Dovecot の fts_solr プラグインをインストールし、設定します。
% sudo apt-get install dovecot-solr
Dovecot の基本的な設定はなされているものとして、fts_solr 関係では以下のような変更を施します。まず、IMAP のプラグインとして、fts および fts_solr プラグインを有効化します。設定ファイルは /etc/dovecot/conf.d/20-imap.conf
です。protocol imap { ... }
内の mail_plugins の設定を変更します。
--- a/dovecot/conf.d/20-imap.conf +++ b/dovecot/conf.d/20-imap.conf @@ -13,7 +13,7 @@ protocol imap { #mail_max_userip_connections = 10 # Space separated list of plugins to load (default is global mail_plugins). - #mail_plugins = $mail_plugins + mail_plugins = $mail_plugins fts fts_solr # IMAP logout format string: # %i - total number of bytes read from client
fts_solr プラグインの設定
次に、プラグインの設定を行います。設定ファイルは /etc/dovecot/conf.d/90-plugin.conf
で、plugin { ... }
内に2行ほど追加します。
fts = solr
により、fts のバックエンドとして solr を使うことを指定します。
fts_solr =
の break-imap-search
は IMAP4 の検索コマンドの BODY や TEXT などの検索条件で高速検索ができるようにしてしまう指定です。最近の 2.1 系の Dovecot では不要になってます。
fts_solr =
の url=...
では、Solr のサーバーにアクセスするための URLを指定します。ここでは※1で設定した http://localhost:8080/ 内の http://localhost:8080/solr/ を指定します。負荷分散のため、Dovecot のインストールされているマシンと、Solr をインストールしたマシン(クラスタ)を分離した場合はここでの指定を変えれば良いのだと思います。
--- a/dovecot/conf.d/90-plugin.conf +++ b/dovecot/conf.d/90-plugin.conf @@ -8,4 +8,6 @@ plugin { #setting_name = value + fts = solr + fts_solr = break-imap-search url=http://localhost:8080/solr/ }
Solr のスキーマの設定
次に、Solr のスキーマとして、Dovecot 用のスキーマを設定します。/etc/solr/conf/schama.xml
を、Dovecot のソースコードに付属している solr-schema.xml
で置きかえます。solr-schema.xml
は、いずれかの方法で入手できます。
apt-get source dovecot
でソースコードを取得すると、doc/solr-scheama.xml
にあります- 開発元のリポジトリ、http://hg.dovecot.org/dovecot-2.0/file/tip/doc/solr-schema.xml にもあります
Solr のスキーマを日本語向けに変更
この schema.xml では日本語がうまく扱えないので、いくつかのフィールドを日本語向きの処理に変更します。(Solr チュートリアル 〜初めの一歩〜: 日本語の扱い CJKTokenizer を使ったバイグラム方式 を参考にしました)
--- a/solr/conf/schema.xml +++ b/solr/conf/schema.xml @@ -15,6 +15,13 @@ want to modify the tokenizers and filters. <fieldType name="float" class="solr.FloatField" omitNorms="true"/> <fieldType name="boolean" class="solr.BoolField" omitNorms="true"/> + <fieldType name="text_cjk" class="solr.TextField" positionIncrementGap="100"> + <analyzer> + <tokenizer class="solr.CJKTokenizerFactory"/> + <filter class="solr.LowerCaseFilterFactory"/> + </analyzer> + </fieldType> + <fieldType name="text" class="solr.TextField" positionIncrementGap="100"> <analyzer type="index"> <tokenizer class="solr.WhitespaceTokenizerFactory"/> @@ -45,8 +52,8 @@ want to modify the tokenizers and filters. <field name="user" type="string" indexed="true" stored="true" required="true" /> <field name="ns" type="string" indexed="true" stored="true" required="false" /> <field name="last_uid" type="boolean" indexed="true" stored="false" /> - <field name="hdr" type="text" indexed="true" stored="false" /> - <field name="body" type="text" indexed="true" stored="false" /> + <field name="hdr" type="text_cjk" indexed="true" stored="false" /> + <field name="body" type="text_cjk" indexed="true" stored="false" /> </fields> <uniqueKey>id</uniqueKey>
Solr を起動
まず、Solr を起動します。
% sudo service jetty start
Jetty が起動するので、ブラウザでアクセスしてみましょう。Jetty がインストールされたのがローカルマシンなら http://localhost:8080/solr/ にアクセスするだけですが、リモートにあるサーバなら ssh の port forwarding で ssh -L 8080:localhost:8080 yourname@your.server.examele.com
のようにした上でアクセスしてみましょう。
Solr というか Jetty のログは標準だと、/var/log/jetty/YYYY_MM_DD.request.log
や /var/log/jetty/YYYY_MM_DD.stderrout.log
で見ることができますので、tail -f で流すなどしておいてください。
Dovecot を再起動
次に、Dovecot を再起動。
% sudo service dovecot restart
検索できるかのテスト
Dovecot にアクセスして、IMAP4rev1 で検索が実行できるか試してみましょう。IMAP4rev1 の STARTTLS によるセキュアな接続を受け付けるようにているのであれば、openssl の s_client コマンドが使えます。
(以下、長い行は ⏎ で折り返してます)
$ openssl s_client -connect your.server.example.com:143 -starttls imap CONNECTED(00000003) (中略) --- . OK Pre-login capabilities listed, post-login capabilities have more. 1 LOGIN yourname pAssWoRd * CAPABILITY IMAP4rev1 LITERAL+ SASL-IR LOGIN-REFERRALS ID ENABLE IDLE SORT SORT=DISPLAY THREAD=REFERENCES⏎ THREAD=REFS MULTIAPPEND UNSELECT CHILDREN NAMESPACE⏎ UIDPLUS LIST-EXTENDED I18NLEVEL=1 CONDSTORE QRESYNC⏎ ESEARCH ESORT SEARCHRES WITHIN CONTEXT=SEARCH LIST-STATUS 1 OK Logged in 2 SELECT Inbox * FLAGS (\Answered \Flagged \Deleted \Seen \Draft NonJunk $Forwarded Junk $MDNSent) * OK [PERMANENTFLAGS (\Answered \Flagged \Deleted \Seen \Draft NonJunk $Forwarded Junk $MDNSent \*)] Flags permitted. * 1282 EXISTS * 0 RECENT * OK [UIDVALIDITY 1234567890] UIDs valid * OK [UIDNEXT 9876] Predicted next UID * OK [HIGHESTMODSEQ 8888] Highest 2 OK [READ-WRITE] Select completed. 3 SEARCH CHARSET UTF-8 TEXT "日本語" * SEARCH 310 413 517 623 899 3 OK Search completed (0.000 secs). 4 FETCH 899 RFC822 * 899 FETCH (RFC822 {3006} Return-Path: <hoge@example.co.jp> X-Original-To: user@server.example.com : (略) : ) 4 OK Fetch completed. 5 LOGOUT * BYE Logging out 5 OK Logout completed. closed
おわりに
ここで使った Solr は Ubuntu 12.04 標準のもので、バージョンは 1.4.1 と幾分古いものです。Solr の最近のバージョンだと、日本語向けにさらにいろんな処理ができるようになってるようなので、それを試してみたいですね。
コメント
トラックバック
このエントリのトラックバックURL: http://tkusano.asablo.jp/blog/2013/01/04/6680218/tb
※なお、送られたトラックバックはブログの管理者が確認するまで公開されません。
コメントをどうぞ
※メールアドレスとURLの入力は必須ではありません。 入力されたメールアドレスは記事に反映されず、ブログの管理者のみが参照できます。
※なお、送られたコメントはブログの管理者が確認するまで公開されません。
※投稿には管理者が設定した質問に答える必要があります。