ScalaからSolr3.6に接続してみる

scalaからSolrに接続するように試してみた。まずはSolrjを直接使ってsolr3.6に接続してみようと、以下のようなコードを書いてみた。

package test {

    import org.apache.solr.client.solrj.impl.HttpSolrServer
    import org.apache.solr.common.params.ModifiableSolrParams

    object Main {

        def main(args: Array[String]): Unit = {
            println("hello")
            val server = new HttpSolrServer("http://localhost:8983/solr")
            var params = new ModifiableSolrParams
            params.set("q", "*")
            val response = server.query(params)
            println(response)
        }

    }
}

さて、これを動かしてみようとするも、NoClassDefFoundErrorが発生してしまって動かない。

なぜだ?と思ったら、Solrj使うには同梱されているライブラリだけじゃなくてhttpclient(4系)が必要らしい。

Ubuntu系だとaptで入るようなのでaptで入れてみた。

$ sudo apt-get install libhttpclient-java
$ sudo apt-get install libhttpmime-java

eclipseで試してたので、インストール後、ビルドパスに以下のjarファイルを追加。

  • httpclient-4.1.1.jar
  • httpcore-4.0.1.jar
  • httpmime-4.1.1.jar

これでとりあえずはSolrからデータが取得できるようになったようだ。

PHPでPrivateなメソッドをテストする

ユニットテストを書くとき、privateメソッドやprotectedメソッドまでテストすべきかどうかというのはまあ微妙な所で、ユニットテストは外から見える振る舞いだけをカバーしておいて、内部の実装は自由にしておくべきなのかもしれないけれども、内部メソッドのテストまで書く場合の方法について。

内部メソッドにはそのままではアクセスできないので、ReflectionのsetAccesibleメソッドを使用して公開状態を変更してやることにより、内部メソッドまでアクセスすることができるようになる。

PHPUnitでテストする場合、こんな感じ。

<?php
class Foo {
    private function bar() {
        return 'hello!';
    }
}

class FooTestCase extends PHPUnit_Framework_TestCase {
    public function testBar(){
        $method = new ReflectionMethod('Foo', 'bar');
        $method->setAccessible(true);
        $this->assertEquals('hello!', $method->invoke(new Foo));
    }
}

PHPだとそんなに出番のないReflectionクラスだけど、こういう時は便利。

PHP5.3.3(windows)のgo-pear.batが動かねぇ

わけあってPHP5.3.3なんていう過去の遺物を使っているのだけど、PEAR使おうと思ったらgo-pear.batが動かなかったのでメモ。

これを参考に、

@ECHO OFF
set PHP_BIN=php.exe
%PHP_BIN% -d output_buffering=0 PEAR\go-pear.phar
pause

これを

@ECHO OFF
set PHP_BIN=php.exe
%PHP_BIN% -d output_buffering=0 -d phar.require_hash=0 PEAR\go-pear.phar
pause

に書き換えてあげる必要がある。

Symfony2のasset内のcss等から画像のパスを解決する方法が欲しい

Symfony2でBundle内のResources/public/cssなどに配置されたcssやjsからResources/public/images/内の画像等を使用する場合のスマートな方法って無いんでしょうか?

Railsだと、http://guides.rubyonrails.org/asset_pipeline.html にscssやjsなどから指定するための方法が解説されてるんですが、同じような指定ができると嬉しいのですが。

Solr3.6の日本語形態素解析エンジン Kuromoji

昔は形態素解析分かち書きしたい場合、Senを使ってやるのが普通だったと思うんだけど、3.6からはKuromojiという形態素解析エンジンが組み込まれているらしい。そしてexampleには最初からtext_jaというフィールドタイプが組み込まれており、すぐに試せる状態になっている。example/solr/conf/schema.xmlの726行からがtext_jaの定義。

KuromojiにはNormal, Search, Extendedの3種類のモードがあり、Normalは通常の形態素解析、Searchは複合語をなるべく短い単語ごとに分割するモード、ExtendedはSearchモードをベースに、未知語をuni-gramに分割するモードらしい。schema.xmlを見ると、デフォルトではSearchモードに設定されている。

どのような形で分かち書きされるかは、Solr AdminのAnalysys http://localhost:8983/solr/admin/analysis.jsp から試せる。

Extendedモードは辞書にない用語、例えば「きゃりーぱみゅぱみゅ」は「きゃ|り|ー|ぱ|み|ゅ|ぱ|み|ゅ」に分かち書きしてくれるし、なかなか良さそうな気がする。

Solrを動かしてみる

aptから入れる場合

とりあえず手軽に試してみたければ、Ubuntu系OSの場合aptを使って

$ sudo apt-get install solr-common solr-jetty

もしくはTomcatがよければ

$ sudo apt-get install solr-common solr-tomcat

でインストールできると思われる。でもバージョンが 1.4.1なので、今回は最新版(3.6.0)を落としてきて使うことにする。

aptを使わないで動かしてみる場合

まず、インストール前にjavaが入っているか確認。入っていなければ入れる。OpenJDKでもOracleJDKでもいいと思う。

$ java -version
java version "1.6.0_24"
OpenJDK Runtime Environment (IcedTea6 1.11.1) (6b24-1.11.1-4ubuntu3)
OpenJDK Server VM (build 20.0-b12, mixed mode)

1. Solrのパッケージ(3.6.0)をダウンロード

Solr公式ページhttp://lucene.apache.org/solr/を開き、

右側のDownloadリンクhttp://www.apache.org/dyn/closer.cgi/lucene/solr/3.6.0をたどる。

適当なミラーを選択する。

(今回は理研http://ftp.riken.jp/net/apache/lucene/solr/3.6.0/

ブラウザからダウンロードするか、もしくはリンクをコピーしてコンソールからダウンロード

$ mkdir packages/solr
$ cd packages/solr
$ wget http://ftp.riken.jp/net/apache/lucene/solr/3.6.0/apache-solr-3.6.0.tgz
$ #これから中を見てみるかもしれないのでソースも落としておく
$ wget http://ftp.riken.jp/net/apache/lucene/solr/3.6.0/apache-solr-3.6.0-src.tgz
$ tar xf apache-solr-3.6.0.tgz
$ #適当な場所に移動
$ mv apache-solr-3.6.0 ~/path/to/dir/
$ cd ~/path/to/dir/apache-solr-3.6.0/

2. 動作確認

$ cd example
$ java -jar start.jar
...
2012-06-16 10:54:05.667:INFO::Started SocketConnector@0.0.0.0:8983

8983番で起動しているようなので、アクセスしてみる。

ブラウザでSolr Admin http://localhost:8983/solr/admin/を開く。ページが開ければ正常。

3. テストデータを入れる

まずは同梱されているテストデータを入れてみる。Solrを起動したまま以下の操作を実行。

$ cd exampledocs
$ ./post.sh *.xml

4. 検索してみる

まずは全項目。Query Stringを*:*のまま実行。とりあえず色々結果が返却される。全件該当するはず。

次に絞り込み。Query Stringをname:iPodとして実行。nameフィールドに"iPod"が含まれるもののみ返却されるはず。

ひとまずこんな感じ。次は日本語、特に形態素解析を使った構成やプラグインの書き方について調べてみようかと思う。

anarchy golf (multi_key sort)

30.multi_key sort。部分適用でComparator作ってsort。Scalaで1位(他に誰もやってない)。しかしLanguage Rankingは30位…。

val s=io.Source.stdin.getLines.toList
def f(k:List[Int],x:Array[String],y:Array[String]):Boolean={val a=k.head
if(x(a)==y(a))f(k.tail,x,y)else x(a)<y(a)}
s.tail.map(_.split(' ')).toList.sort(f(s.head.split(' ').toList.map(_.toInt-1),_,_))map{a=>println(a mkString " ")}