RubyでSolrを使うときに気をつけること

はじめに


タイトルは釣り臭が半端ないですねw

正確なことを言うと使用ライブラリは、
特性を理解の上で使いましょうということが言いたいだけです

RubyでSolrを使う際のライブラリと言えば


大体、以下の2つになると思います

前者は、シンプルな機能に対して、後者は多機能になっています

RSolr


ここら編は、ドキュメントを見たほうがよいですが自分の理解をダラっと

  • 接続やプロキシは、自分で設定できる(タイムアウトやリトライ設定も可能)
  • 上記の為、(実装に応じるが)自由に検索先のスキーマを変更できる
  • 検索クエリ(ファセットクエリ等も含む)は自前で実装しないといけない
  • rowsやstartなども自前で実装する必要がある
  • 更新や削除(クエリベースやidベースで)もできる上にメソッドとして用意してある
  • responseはハッシュになっているので、自前で検索結果を整形(ActiveRecordオブジェクト等)する必要がある
  • ページングも対応している

一声で言うと・・・

  • クエリ構築は自前でやる必要がある
  • 検索結果の整形も自前でやる必要がある
  • 実装次第で、接続先のSolrも自由に変更することができる

シンプルとか言っておきながら、結構ありますね^;;

実際、使うとわかりますがかなりシンプルですよ

sunspot


こちらもドキュメントを見たほうがよいのですが・・・

  • 検索クエリ(facetクエリなら)をDSLライクに記述できる
  • 検索はdismaxで行ってくれる
  • 検索クエリの結果はActiveRecordオブジェクトで取得できる
  • 全文検索も直感的に記述できるうえにboost値も設定できる
  • ページングやグルーピングにも対応している
  • 緯度、経度のデータも検索できる
  • 検索ハイライトやスキーマデータの結合にも対応している
  • indexingもsunspotのみで完結することができる(削除もできます)
  • 勿論、手動でクエリを構築することも可能
  • sunspot自体がRSolrに依存しているので、その気になればRSolrの機能も一応使うことができる

これだけ、高機能なので当然の如く欠点もありまして・・・

  1. Solrのスキーマ定義がsunspotに依存した形になってしまうこと
  2. indexするデータの一部もsunspotに依存した形になってしまうこと
  3. Solrのフィールドに対応する形でActiveRecordのmodelクラスに定義が必要になること
  4. sunspotが吐き出すクエリを理解しないと使いづらいこと
  5. sunspot自体がmethod_missingを使った実装なのでコードが読みづらいこと・・・

日本語を扱う場合の注意点


基本的に、検索文字列の処理はSolr側のtokenizerで行われます。

ところがsunspotで日本語を使う場合だと、全文字列がエスケープされてしまいます。

例えば、「あいうえお」を検索したい場合だと「\あ\い\う\え\お」になってしまいます。

因みに、英語検索は問題ありません。

原因がどこにあるかと言うと、 restriction.rbにあります。

具体的な箇所は、このmodule内で使用されているescapeメソッドが原因です。
このescapeメソッドの実装は、char.rbですね。
つまり、RSolr側の不具合に近いでしょう。
また、RSolrを使って自前で実装するときもこのescapeメソッドを使用しないほうがいいです。

sunspotの依存gem側の問題なので、簡単に修正するのも難しいですね。

対処方法は?


モンキーパッチを使えば、対処できました。

escapeメソッドを使っているところを全部上書き実装すればいいだけです。

Railsで使う場合だと、「config/initialize/sunspot.rb」みたいなのを作ればいいですね。
その中で、上記の処理を使えば対応可能です。

まぁ、根本解決ではないなと思いますが・・・