Solr

2011年03月01日

Ruby1.9.2でsolr-rubyとerbを使ったら Encoding::CompatibilityError

Solr-ruby での検索の戻り値をパースして erb でHTMLファイルに書きだそうとしたところ、erb のテンプレートファイルの中に日本語を書いた途端にエラーが出るようになってしまった。
Encoding::CompatibilityError: incompatible character encodings: ASCII-8BIT and UTF-8

erbファイルの頭でエンコーディングの宣言ができると知り、 <%# coding: UTF-8 %>と書いてみたりしたものの、全く効果なし。

そこで、 erb 側で item.name という変数で出力している変数のエンコーディングを item.name.encoding として出力して見てみたところ、ascii になっていた。日本語の書いてある erb テンプレート側が UTF-8 だから、異なるエンコーディングの文字列同士の結合ということでエラーになっているらしい。

本当ならば solr-ruby で検索した戻り値の時点で適切にエンコーディング情報が入っていればいいのだけど、solr-rubyのwikiを見ても、あまり多言語対応の部分には期待が持てない感じ。

シンプルに対応したかったので、solr-ruby からの戻り値のハッシュの値のエンコーディングを強制的に指定して回ることにした。
params.each { |k,v|
  params[k] = v.encode('UTF-8')
}
が、相変わらずエラー発生。encode メソッドではダメらしく、force_encooding に変更したところ、無事生成できるようになった。
params.each { |k,v|
  params[k] = v.force_encoding('UTF-8')
}
Ruby 1.9 の文字コード関係は意外とハマると大変、という印象。。。

maru_tak at 18:47|PermalinkComments(0)TrackBack(0)

2009年01月16日

SQLで行番号を取得する

SolrのData Import HandlerにDBをクロールさせてインデックスを作成する場合、スキーマには primary key のフィールドを定義する必要がある。

しかし、当該テーブルの主キーが2フィールドで構成されていたりすると、ユニークな値を単独で持つフィールドがないので困ってしまう。primary key の設定がないと Solr の起動時にこけてしまうので、意味的には何でもいいからユニークな値が欲しくなる。

そこで行番号を取得したくなるのだが、各DBにはそのような行番号を取得するための擬似列があるようだ。

Oracle ・・・ rownum
Sqlite3 ・・・ rowid

たとえば、sqlite3 の場合、
select rowid, name from person;
というように記述すると、1列目に行番号が入る。SolrのEntitiyの抽出方法定義する際のSQLで利用すると良いのではないか、と思う次第。

maru_tak at 09:48|PermalinkComments(0)TrackBack(0)

2008年12月30日

Solr1.3(Jetty)でSenを使えるようにする設定方法

現在、Solr1.3をいろいろいじくる際には、最初からついてくるJettyのExampleをそのまま流用して使っている。

Senの組み込みもできているのだが、あれこれ試行錯誤をしながらセットアップしたので、どれが本当に必要な設定なのか、実はよく分かっていないという状態。が、一度はうまく動いているものを下手に変更して動かなくなるのは避けたい。そんなこんなで「触らぬ神にたたりなし」だったのだが、今後の新規インストールの際に再びハマりそうな気がしたので、Senの組み込みを0からやり直してみた。

参考にさせていただいたのは、いつも参考にさせていただいている下記のページ。ありがとうございます。

日本語形態素解析器Senを導入する その2 lucene-jaのインストール

Solrお試し2


普通に読むと、sen.jar と lucene-ja.jar というファイルを lib フォルダみたいな、クラスパスが通っている所に置けばいいんでしょ?という感じなのだが、いくつかハマリどころとなるポイントが。

1. そこら中の lib フォルダにjarファイルを入れると・・・
このあたりを読むと、jarファイルの置き場所の混乱は根が深いようだ。私もクラスパスの通っている複数の場所にファイルを置いてしまったことでハマった。それっぽい所に片っ端からファイルを置いておけば、どれかが正解で動くようになるというのは逆なこともある、と勉強になった。

2.起動時に -Dsen.homeを指定しないといけないこと
これがなくても Solr はエラーなく起動するのだが、検索した瞬間にエラーになる。

■手順

Windows XPで c:\temp にSolrをインストールした。なお、sen は c:\java\sen にあり、辞書等はできているものとする。環境変数では jdk 以外には特にクラスパスは通していない状態。


  1. c:\temp に apache-solr-1.3.0.zip を解凍 → apache-solr-1.3.0というフォルダができる

  2. c:\temp に lucene-ja-2.0test2.zip を解凍 → lucene-ja というフォルダができる

  3. C:\temp\apache-solr-1.3.0\example\lib に C:\temp\lucene-ja\libからlucene-ja.jarとsen.jarをコピー。

  4. C:\temp\lucene-ja はもはや不要なのでフォルダごと消してしまう。

  5. C:\temp\apache-solr-1.3.0\example\solr\conf\schema.xml の191行目(fieldType name="text" の後)に形態素解析の対象となる型(名前は任意のものをつけてよいのだが、ここでは text-sen とする)を追加する定義を記述。
    <fieldType name="text_sen" class="solr.TextField">
    <analyzer class="org.apache.lucene.analysis.ja.JapaneseAnalyzer"/>
    </fieldType>

  6. Solrを起動
    cd C:\temp\apache-solr-1.3.0\example
    java -Dsen.home=c:\java\sen -jar start.jar

  7. 下記の表示が出たら起動成功
    情報: [] Registered new searcher Searcher@dcb03b main
    2008-12-30 20:11:05.859::INFO: Started SocketConnector @ 0.0.0.0:8983

  8. 管理画面にアクセス
    http://localhost:8983/solr/admin/analysis.jsp

  9. Fieldのドロップダウンをnameからtypeに変更。右のテキストボックスに text_sen と記入。

  10. より詳しい情報が見えるようにverbose output にチェックを入れる。

  11. Find Valueの右の欄に「今日の天気は晴れ」と入れてAnalyzeボタンを押し、下記のように解析されたら成功。
    term position 1 2 3 4 5
    term text 今日 の 天気 は 晴れ
    term type 名詞-副詞可能 助詞-連体化 名詞-一般 助詞-係助詞 名詞-一般
    source start,end 0,2 2,3 3,5 5,6 6,8

    payload




-------おまけ--------
solr.warの中の web-inf/lib に入れるという手もあるようだ(warファイルを作り直すので面倒だけど)。

  1. C:\temp\apache-solr-1.3.0\example\webapps\solr.war をZIP解凍 → solrというフォルダができる

  2. warファイルを作る
    cd C:\temp\apache-solr-1.3.0\example\webapps
    jar -cvf c:\temp\solr.war *

  3. c:\temp に solr.war ができるので、これを C:\temp\apache-solr-1.3.0\example\webapps に上書きコピー




maru_tak at 21:26|PermalinkComments(1)TrackBack(0)

2008年12月23日

配列からHash

Solrの検索結果をwt=rubyリクエストすると、ファセットの配列を含むハッシュが返ってくる。

てっきり [[ファセット1,個数][ファセット2,個数][ファセット3,個数]...]のような多重配列かと思っていたら、[ファセット1,個数,ファセット2,個数,ファセット3,個数...] のような、名前と個数が交互に登場する1次元の配列だった。

これだと中身を取り出すときにインデックスを2ずつインクリメントしないといけないので使いづらいな、と思っていた。

が、Hash[*array]で、そのままハッシュにできるらしい!

Rubyリファレンスより

ary = [1,"a", 2,"b", 3,"c"]
p Hash[*ary]

# => {1=>"a", 2=>"b", 3=>"c"}


しかし、ハッシュにすると取り出すときに順番が崩れてしまう。元の配列はちゃんと個数の降順にソートされているので、やはり多重配列で返してくれた方がありがたい気がするのだが、なぜこういう仕様になっているのだろう?

仮に多重配列が採用されていた場合、Arrayクラスの transpose が便利そう。これは配列を行列みたいなものとみなして、行列でいうところの縦の列に配列をまとめなおしてくれる、というもの。言葉だと分かりにくいのでコードをば。

score = [["car1", 50],["car2",77],["car3",70]]

p score
p score.transpose

(実行結果)
[["car1", 50], ["car2", 77], ["car3", 70]]
[["car1", "car2", "car3"], [50, 77, 70]]


maru_tak at 17:40|PermalinkComments(0)TrackBack(0)

2008年09月24日

solr-ruby を使ってみる

今日は solr-ruby を使ってみる。

まずは gem install solr-ruby でインストール。バージョン0.0.6が入った。

Solr-rubyのWikiを参考にしたが、サンプルも1個しかなくて恐ろしくシンプル、という印象。SolrではもともとCRUDをURLを通してできるのだから、このシンプルさも当然なのかもしれないが、Javaでクエリーを組み立てる時のコードを見てからこれを見ると、何か抜け落ちているのではないかとさえ思ってしまう。

下記のコード実行前には当然ながら Solr を起動しておく。
require 'solr'

# Solrに接続。引数を省略すると接続先はlocalhost:8983/solr とみなされる。
conn = Solr::Connection.new('http://localhost:8983/solr', :autocommit => :on)

# ドキュメントをインデックスに追加
conn.add(:id => 123, :title_text => 'Lucene in Action')

# ドキュメントをアップデート
conn.update(:id => 123, :title_text => 'Solr in Action')

# ほげというキーワードで検索。luceneのクエリーシンタックスも通る。レスポンスは hits に配列のように入るようだ。
response = conn.query('ほげ')
print response.hits[0]

#autocommit=>offにした場合のデータコミット
conn.commit

#アップデート後に行うインデックスファイルの最適化
conn.optimize

# そのままループで取り出し。each すら無いのが凄い・・・。
conn.query('action') do |hit|
puts hit.inspect
end

# 削除
conn.delete(123)


もう一回、lucene のオブジェクトをおさらいしておくことにする。


maru_tak at 23:15|PermalinkComments(0)TrackBack(0)

2008年09月23日

Solrに日本語のデータをCSVからロード

今日は Solr に日本語のデータを入れてみることにする。これで業務でも実際に扱うようなデータが入ると、俄然やる気が出てくるというもの。

方法は Solr Wiki の Updating a Solr Index with CSV のとおり。Cygwinに curl が入っているので、これでPostを行うことでデータを入れる。

まずは Solr を昨日の日本語化を何もしない状態で起動し、その状態でデータを入れてみることにする。

CSVの区切り文字はマニュアルでは、デフォルトがコンマ区切り、上記Wikiの最後の例ではTab区切りになっているが、指定ができるみたいなのでセミコロン区切りのものを使ってみる。

CSVの1行目のヘッダーは、現在 schema.xml に入っているものの中から、実際のデータに合いそうなものをピックアップして構成する。読み込ませたくない列はヘッダーにnullを入れておくとスキップしてくれるらしい。できたヘッダー行はこんな感じ。
id;name;;sku;price;weight;features


CSVの文字コードはUTF8じゃないといけないみたいなので、CSVファイル全体をUTF8に変換して、いざ読み込み。

curl --data-binary @c:/new/sample.csv -H 'Content-type:text/plain; charset=utf-8' http://localhost:8983/solr/update/csv?separator=%3b&commit=true


こちらのエントリは参考になります。

が、実行時にサーバー側のコンソールを見ていると、なぜか最後の commit=true が取れた状態で解釈されているみたい。。。これがないと、インデックスに対する変更が commit されないので、実行後に再び curl 'http://localhost:8983/solr/update/csv?commit=true' を実行しておいた。

何行かデリミターとデータが分離できずに、その行だけフィールドの数が合わないというエラーがなぜか出たが、その他のデータは読み込めているようだったので、とりあえずは無視。FAQによると、マルチバイト関連のエラーはJettyが原因になっていることが多いとのこと。Tomcatなら大丈夫らしいが、前みたいにデプロイではまると嫌なので、今日は先に進むことにする。

本当はサーバーに直接ファイルから読んでもらう remote streaming にしたかったのだが、solrconfig.xml の requestParsers enableRemoteStreaming="false" を true に変えて読んでみたものの、ヘッダー行を一つなぎのフィールド名として解釈してしまい、「そんなフィールドはない!」と怒られて読み込めなかった。デリミターを変えているからいけないのか、日本語が入っているからいけないのか、切り分けができていないが、ここで時間をとられるのも嫌だったので、上記の代替方法でロードができたので先に進む。

以上のところまで行ってからは、管理画面で検索ができるようになった。日本語に対応したTokenizerを使っていないので、スペースで区切られた単語との完全一致しかマッチしないが、ちゃんと検索できているようだ。

次は、いよいよfacet検索を試してみる。リクエストのURLに下記のパラメーターをつけてみた。

・facet=true ・・・これでfacet検索がONになる。
・facet.field=price ・・・facet対象フィールドの選択。とりあえずpriceに。
・facet.mincount=1 ・・・ 対象が1件以上あるものに限定するために指定。
すると、こんな感じのリストが追加で出るようになった。
</result>
<lst name="facet_counts">
<lst name="facet_queries" />
<lst name="facet_fields">
<lst name="price">
<int name="354.0">4</int>
<int name="732.0">2</int>
<int name="207.0">1</int>
<int name="522.0">1</int>
</lst>
</lst>
<lst name="facet_dates" />
</lst>
しかし、こんなfacetではあまり実用性がないので、やはり、schemaを独自のものでちゃんとやり直してみないといけませんな。。。

なお、検索結果は、wt=ruby と書くとRubyのハッシュで返ってくるとのこと。結果をRexmlでパースするのは大変そうだと思っていたのだが、こちらの方がハンドリングしやすいかも。



maru_tak at 22:30|PermalinkComments(0)TrackBack(0)

Solrひもとき中

Solrについて、再び勉強中。

まずは %solr_home%\docs にあるドキュメントを読んでみる。基本的には Solrのサイトに載っているものと同じようだ。

次に、Solr Wiki の Installation and Configuration のページを呼んでみる。

それによると、%solr_home%\example\solr\conf には2つ設定ファイルがある。

solrconfig.xml ・・・ Solrの基本設定
schema.xml・・・型の定義や、読み込むスキーマの定義


とりあえず、例題で用意されているデータ以外の手持ちのデータを読み込もうと思ったら、schema.xml に定義するようだ。

デフォルトではそれぞれの型に対してAnalyzerが既に設定されているが、日本語のデータでは役に立たないものも多そうなので、ざっくりと再定義が必要そうだ、と思ったところ、こちらの記事にTEXT型の日本語対応の方法が書かれていた。

その後、ドキュメントの中の用語を調べていてIBMのサイトのSolr1.1の解説をしている記事に辿りついた。以前も見たことがあったのだが、そのときは Lucene を全く理解していなかったので、ちんぷんかんぷんだったことを覚えている。が、今回は何を書いてあるのか理解できるのがちょっと嬉しい。

しかし、今になって思うと、前回理解できなかったのは、知識のせいだけではないとも感じる。そう、日本語訳がひどすぎるのだ。この段落なんかは脳みそがウニになりそうになって読み、全く分からなかった覚えがある。
分析は、検索操作中にクエリーに対して適用することもできます。原則として、クエリーに対して実行される分析は、索引を付ける文書に対して実行される分析と同じでなければなりません。このようなコンセプトが初めてのユーザーは、文書トークンではステミングを行ってクエリー・トークンでは行わないという誤りを犯しがちですが、それによって多くの場合は検索結果がゼロ件になってしまいます。Solr の XML 構成では、後で説明するように単純な宣言を使うので、Analyzer を簡単に作成することができます。
複数のソースから勉強することの大事さを感じた一瞬だった。


maru_tak at 00:31|PermalinkComments(0)TrackBack(0)

2008年09月19日

Solr1.3リリース

Solr1.3がリリースされたらしい。

過去にまともに動かせていないのに、このBlogの一番アクセスが多い記事はSolrのインストールについてのものだったりする・・・。

世の中にゴミ情報を撒き散らす存在にならないためにも、1.3はきちんとインストール体験談を掲載せねば。今やってる仕事にもど真ん中だしね。



maru_tak at 02:14|PermalinkComments(0)TrackBack(0)

2008年09月12日

Luceneを通じて、検索エンジンの裏側を想像してみる

SolrはLuceneがベースになっているので、まずはここを理解しないと、と思い、最近はLuceneの本を読んでいる。これが非常に面白く、意外とSEOを考える上で勉強になっている。Lucene自体はAPIで、本は基本的にその使い方を説明しているだけにもかかわらず、である。

Webマーティングの世界のコンテキストで語られるSEOの世界では、クローリングについては情報がそれなりにあるのだが、その先のインデキシングとスコアリングのロジックについては、「検索エンジン各社の企業秘密なので」という扱いでほとんど詳細が語られることがない。あったとしても、検索結果から帰納的に「こういうページを高く評価しているようだ」という、都市伝説的な法則が語られているに過ぎないことが多い。

GoogleのOfficial Blogが語る通り、今やGoogleは1日1つ以上のロジック変更を行っており、1クエリーをさばくためには100台以上のサーバーの処理を経由する。その過程で行われている処理とパラメーターを知らないと、効果的な対策なんて考えようがないのではないかと思う。

が、世間で言われているロジックは常に単純だ。素人考えでも想像ができるレベルに留めないと、理解してもらえないからなのかもしれないが、例えていうなら自動車の掲示板でよく見る「燃費向上運転テクニック」と話が似ていると感じることが多い。

電子制御の自動車においては、ECUが燃料の噴射量をどのように制御しているかを知らないと、最大限のエコラン運転はできないと思う。でも、そこがキモだなんて話自体を知っている人が少ないので、仕組みに詳しくない人だけが集まる掲示板では「なぜそれが燃費向上につながるのか」という大枠は合っていても、例外となるケースの存在が全くすっぽ抜けたまま、あーだこーだと議論が戦わされているのを目にすることがある。

戦うためには、敵を知ることが重要。そう思う。

Luceneは Information Retrievalという学術分野の理論の実装例なので、その中身をのぞくこと自体が「へー!」ということの連続だ。転置インデックスやBigramなど、多くの要素はSEOのタームとして聞いたことがあるものなのだが、それらの仕組みや他の方式との比較、それが必要とされる背景、という話はこの本を読んで初めて知ったものがいくつもある。

私なりの理解では、検索エンジンは(そしてついでにレコメンデーションエンジンも)、AとBの似ている・似ていない度合いを統計的に図るために、レアケースが全体を引きずらないように、各要素のスコアをうまく減衰しながら0から1の間に収まるようにノーマライズしつつ積算している、というのが処理内容の本質なのだと感じた。

それを行うためのフィルターには、いくつか種類があり、それらをパイプ処理のように連鎖させる(これが1クエリーをさばくためのサーバー台数が増える所以と想像)のだが、その際にどれをどれだけ効かせるかというのが検索エンジン各社のロジックのチューンニングのキモなのだと思う。実際にGoogleがチューニング手法についてUSで特許をとっているが、読んでみるとまあパラメーターの設定が細かいこと細かいこと。そんなにパラメーターがある一方で、あらゆる種類のタームでも常に人間がベストと感じる結果を出す一義的なロジックを作る、なんてことは並大抵のことではないと感じる。

一方で、この本を読んでもまだまだナゾなのが、チューニング結果の評価方法。入力の変数が多すぎると、検索結果が実際にどういう順番に帰着するのかは算出してみないと分からんということになりがち。そうやってできた個々の検索順位の評価を人間の感覚評価で行うのは量的にも質的担保の意味でも無理なので、結果の良し悪しまでもユーザーの行動結果から統計的な手法で自動学習しているのがGoogle。その評価方法というのはほとんど聞いたことがないのだが、最近出たオライリーの集合知プログラミングの本がこのあたりに触れているようなので、Luceneの本が腹に落ちたら腰を据えて読んでみようと思う。

maru_tak at 01:45|PermalinkComments(0)TrackBack(0)

2008年08月03日

Solrふたたび

<追記>
Solr1.3(Jetty)でSenを使えるようにする設定方法

-----この記事はSolr1.3が出る前のものです-------

最近、Information Retrieval についての文献をいろいろ読んでいる関係で、再び Solr にチャレンジしてみたくなった。

前回はどちらかというとSolrそのものよりも、Tomcatの設定が分からなくて挫折したという印象があったので、今回はExampleとして添付されている Jetty を使うバージョンにチャレンジしてみた。

その前に改めてドキュメントを読んでみる。前回読んだときよりも遥かによく理解できた。ファセット検索は確かに下手なDBを使うアプリを組むより良さそう。

しかし、今回も日本語化のところでつまづいた。必要な jar ファイルをコピッてきて起動時に Sen のインストールディレクトリを指定して java -Dsen.home=(Senのインストールパス名) -jar start.jar のように起動するのだが、どうやっても起動時にエラーが出る。

2008-08-03 18:37:32.937::WARN: Config error at /solr/*solr.war name="extractWAR">trueorg/mortbay/jetty/servlet/webdefault.xmlsolr/homesorl
2008-08-03 18:37:32.937::WARN: EXCEPTION
java.lang.IllegalStateException: No Method: /solr/*solr.war e="extractWAR">trueorg/mortbay/jetty/servlet/webdefault.xmlsolr/homesorl on class org.mortbay.jetty.Server
at org.mortbay.xml.XmlConfiguration.call(XmlConfiguration.java:548)
at org.mortbay.xml.XmlConfiguration.configure(XmlConfiguration.java:241)
at org.mortbay.xml.XmlConfiguration.configure(XmlConfiguration.java:203)
at org.mortbay.xml.XmlConfiguration.main(XmlConfiguration.java:919)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.mortbay.start.Main.invokeMain(Main.java:183)
at org.mortbay.start.Main.start(Main.java:497)
at org.mortbay.start.Main.main(Main.java:115)



何が問題になっているのかが、やっぱりよく分からない。

そもそも lucene とか sen との連携を全く理解していないので、sen.homeの指定の仕方がこれで合っているのかもアヤシイ。

結局、今回も断念した・・・。

が、前回調べたときよりも確実に日本語のBlogでの「スゲー」という声も増えているし、Railsから利用できるプラグインも出たりしているので、そろそろ登場するというバージョン1.3が出たら、あちこちで一気に紹介されそうな気もする。

Solrの開発者には最近日本人が入ったそうなので、きっとそのバージョンでは日本語の設定でつまづくことはなかろう。それまで他のことを勉強するとしよう。





maru_tak at 18:43|PermalinkComments(0)TrackBack(0)

2008年04月07日

Solrその後

Tutorialは読み終わった。管理画面も一通りいじってみた。

そこで、手持ちのデータで検索をしてみようと思いたつ。データのフィードはcurlなどでpostすればよいらしい。XMLのみならず、CSVでもフィードできるのがうれしい

$ curl "http://localhost:8983/solr/update/csv?stream.file=exampledocs/ProductDesc.txt&separator=;&header=false&fie
ldnames=id,short,long,,,,,,"

みたいに実行してみたのだが、コンソールにエラーが・・・。そこで表示されている日本語は全部「?」に化けている上、フィールドの数が合わないというエラー。

ひょっとしてSolrってそのままでは日本語に対応していないのか?と思い、検索してみると、どうもそうらしい。こちらの記述を見ながら、lucene-ja.jar などをコピーしてみる。

java -Dsen.home=c:/java/lucene-ja/lib -jar start.jar

-Dsenの部分の書式がよく分からない。。。が、実行結果はエラー。まともに立ち上がらなくなってしまった。

情報: Reading Solr Schema
2008/04/07 0:55:29 org.apache.solr.schema.IndexSchema readConfig
情報: Schema name=example
2008/04/07 0:55:29 org.apache.solr.core.SolrException log
致命的: java.lang.NoClassDefFoundError: org/apache/lucene/analysis/Analyzer
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(Unknown Source)
at java.security.SecureClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.defineClass(Unknown Source)



Javaのものって、こういうところでひっかかることが多いんですよね。


maru_tak at 00:59|PermalinkComments(0)TrackBack(0)

2008年04月06日

SolrのTomcatへのインストールでハマる

早速SolrをTomcat6.0の環境にインストールしてみる。

最初は、IBMの記事を参考にしたのだが、「以下のいずれかの方法で、Solr のホーム・ロケーションを設定します」のあたりで具体的に何をすべきかのかがわからなくなってしまった。

とりあえず、apache-solr-1.2.0.war ファイルはダウンロードしてあったので、これを $TOMCAT_HOME/webapps の下に置いてみたり、TomcatのWebアプリケーションマネージャ(http://localhost:8080/manager/html/)から配備してみたりしたが、いずれも失敗。画面が出るはずのURL(http://localhost:8080/solr/admin/)にアクセスしても、404エラーになってしまう。

Webアプリケーションマネージャ画面上では、Solrが起動していない状態だったので、「起動」のリンクをクリックして起動しても、起動に失敗した旨の表示がさらっと出るだけ・・・。
logs に出力されている localhost.2008-04-06.log を見ると、下記のエラーが出続けていた。

2008/04/06 7:20:20 org.apache.catalina.core.StandardContext filterStart
致命的: フィルタ SolrRequestFilter の起動中の例外です
java.lang.NoClassDefFoundError: Could not initialize class org.apache.solr.core.SolrConfig
at org.apache.solr.servlet.SolrDispatchFilter.init(SolrDispatchFilter.java:74)
at org.apache.catalina.core.ApplicationFilterConfig.getFilter(ApplicationFilterConfig.java:275)
at org.apache.catalina.core.ApplicationFilterConfig.setFilterDef(ApplicationFilterConfig.java:397)
at org.apache.catalina.core.ApplicationFilterConfig.(ApplicationFilterConfig.java:108)
at org.apache.catalina.core.StandardContext.filterStart(StandardContext.java:3693)
at org.apache.catalina.core.StandardContext.start(StandardContext.java:4340)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:791)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:771)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:525)
at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:825)


ということで、「Could not initialize class org.apache.solr.core.SolrConfig」で検索をかけて、先人の知恵を借りることにする。

あちこち調べて、こちらのページの情報でようやく解決。

結局知らなければならなかったこととして下記のものがある。

1. Solrのホームディレクトリを作る必要がある
2.配備場所に隠れた制限がある

私はwarファイルを、アプリケーションのルートディレクトリが並んでいる場所($tomcat_home/webapps)に置けば、warファイルが自動展開されて、URL的には /solr/admin でアクセスできるのだろうと思っていたのだが、それだけでは足りなかったようで、Solr用のホームディレクトリを別に作らなければならなかったらしい。

話がややこしいのだが、上記の情報元によるとTomcat5.5以降では、context file を使うのであれば(?)、そのディレクトリは webapps の外にないといけない(?)とのことで、$tomcat_home 直下に solr というディレクトリを作った。

その中には何を入れるかというと、apache-solr-1.2.0.war を展開すると中に入っている example ディレクトリの中にある、3つのディレクトリ。これら(bin、conf、data)を solr ディレクトリにコピーする。

これでTomcatを起動したところ、Webアプリケーションマネージャ上でも起動した状態となり、http://localhost:8080/solr/admin/ も表示されるようになった。もっと綺麗なリソースの配置方法もきっとあると思うのだが、$tomcat_home/solr の中身を $tomcat_home/webapps/solr にコピーしたりしても、うまく動かなかったので、とりあえずこのままとすることにした。

なお、今回はTomcatで動かすために試行錯誤したが、apache-solr-1.2.0.warを展開した際に中に現れる exapmple ディレクトリの中で、java -jar start.jar を実行すれば、Jetty というサーブレットエンジンが起動し、http://localhost:8983/solr/admin/ で、さきほどの画面をあっさり表示させることができた。

これでようやくTutorialを読む準備ができた。

maru_tak at 18:16|PermalinkComments(1)TrackBack(0)

オープンソースの検索エンジン Solr に興味をもつ

S3のことを調べていたら、Solr の情報に行き当たった。なんと読むのかすらよく分からないこいつはオープンソースの検索エンジンらしい。

「フリーの検索エンジンなら以前からIBMが出していたような・・・」と思ったが、もともとは Java から検索を制御できる Lucene というAPIを基にしているのだそう。それだけならあまり興味もないのだが、特徴の説明を見て驚いた。今はこんなところまでできるのね。。。

Solrの特徴

・商用利用可能な無料のオープンソース検索エンジンサーバ。
・HTTP/XMLによる文書の索引付けと検索。
・Luceneフィールドに「データ型」を導入。
・検索を高速化するための各種キャッシュ機構の装備。
・キャッシュを最大限に利用した高速な絞り込み検索。
・スケーラビリティと運用性を考慮したインデックスレプリケーション。
・「類義語検索」やハイライト表示のための「ハイライター」など各種ツール類の装備。
・管理画面。
・各種プラグイン開発インタフェースの提供による高い拡張性と柔軟性。


これを見て思ったのは、「サイト内検索のASPサービスを行なっています」と言っている会社も結構これを使っているのではないかということ。

私の今までの稚拙なイメージだと、サイト内検索は相当DBのチューニングに長けていないとスケーラブルなものは作れず、だから餅屋が作った商用製品を採用するのが確実、と思っていた。

が、こちらを読んで、考えが変わった。これを自分で商用に使うとかなりいろいろなことができそう。フリーワード検索のみならず、絞込み検索や類義語にまで使えるというのがポイント高し。

奥が深いだけだったら、それこそ RBD も奥が深い。が、Solrは速度的なチューニングにはそれほど心血を注がなくても速いところがさらに魅力的。(こちらによると、ノートPCでも秒間200クエリもさばけてしまうとのこと。RDBじゃ私にはこれは無理。)

クローリングさえなんとかすれば、後はロジックのチューニングが課題となるだけなので、なんとかなるのではないか、という気がしてきた。








maru_tak at 17:16|PermalinkComments(0)TrackBack(0)