以下は、Solr Wiki 中の特に有益と思われる部分の翻訳です。
なぜ文字化けが起きるのか?
Solr は、UTF-8で表現できるすべての文字を索引付けできます(SOLR-96 参照)。 Solr の文字の取り扱いに関する既知のバグはありませんが、いくつかのアプリケーション・サーバー(そして同一アプリケーション・サーバーの異なるバージョンで)多バイト文字の入出力時の不具合が報告されています。特に、Jetty よりは、Tomcat の方が問題が少ないようです。
- XML に埋め込まれた国際文字コード(Jetty 5.1)(訳注: リンク切れ。恐らくこのスレッドと同一と思われる。)
- UTF-8 のサロゲート文字の問題(Jetty 6)(訳注: リンク切れ。)
多バイト文字での問題が起きた場合、Solr のバグかどうかを見極めるために最初にするべきことは、org.apache.solr.util.AbstractSolrTestCase(訳注: Solr 1.4 では利用可だが、現在開発版には、このクラスはもう存在しない。)を使ったユニットテストを書いてみることです。これにより、アプリケーション・サーバーを迂回することができます。
重要な点は、
- 文書(Document)は、Solr サーバーでは、UTF-8 でエンコードされなければならない。もし、ISO (訳注: ISO-8859-x 系単バイト文字コード)でエンコードされた文書を送ると、特殊文字は、余分なバイトが付加されるかもしれない。(UTF-8 で索引付けをやり直すしか修正方法は無い。)
- 検索リクエストを Solr サーバーに送る際に、クライアントは、UTF-8 URL エンコードを施さなければならない。
もし、次のようなやり方でクエリー文字列を取得しようとすると:
1 String value = request.getParameter("q");
ISO として解釈されるため、Solr は、検索に失敗します。(訳注:実際には、サーバーと動作環境に依存するデフォルトのエンコーディングとして解釈されるため、日本語環境では、シフトJISとして解釈されるかもしれません。)
これを防ぐひとつのやり方は、以下の通りです。
1 String encoding = request.getCharacterEncoding();
2 if (null == encoding) {
3 // Set your default encoding here
4 request.setCharacterEncoding("UTF-8");
5 } else {
6 request.setCharacterEncoding(encoding);
7 }
8 ...
9 String value = request.getParameter("q");
もうひとつのやり方は、java.net.URLDecoder/URLEncoder を使用して、全パラメーターの値を UTF-8 に変換することです。
Tomcat で日本語文字等を扱うための設定
HTTP-GET で、国際文字(127より上)を使って Solr にクエリーをかける場合、%表現の UTF-8 エンコーディングを正しく扱えるように Tomcat を構成する必要があります。
Tomcat の conf/server.xml を編集して、適切な Connector 要素に、URIEncoding=”UTF-8″ 属性を追加してください。
<Server ...>
<Service ...>
<Connector ... URIEncoding="UTF-8"/>
...
</Connector>
</Service>
</Server>
上記は、非 ASCII 文字をクエリー要求に含める場合のみ必要なことです。応答に非 ASCII 文字がある場合や、HTTP-POST の本文に非 ASCII 文字がある場合は、Tomcat 側でこのような構成を行う必要はありません。
