RailsでGroongaを使って日本語全文検索を実現する方法MySQL・PostgreSQL・SQLite3の標準機能では日本語テキストの全文検索に難があります。追加するMroonga・PGroongaというプラグインがあります。詳細は以下を参照してください。別途全文検索エンジンGroongaサーバーに任せるという方法もあります。詳細は以下を参照してください。RailsでMySQL・PostgreSQL・SQLite3とGroongaを使って日本語全文検索を実現する方法ここではMySQL・PostgreSQL・SQLite3を一切使わずに、データもGroongaに保存して日本語全文検索を実現する方法を紹介します。Groongaにデータも保存して使うメリットは以下の通りです。Groongaのフル機能を使える検索とデータの取得を一度にできるので速い一方、デメリットは以下の通りです。MySQL・PostgreSQL・SQLite3を使うだけの場合と比べて学習コストが高い(最初にGroongaのことを覚えないといけない)マスターデータを別途安全に管理する必要がある(Groongaにはトランザクション・クラッシュリカバリー機能がないため)このデメリットのうち学習コストの方をできるだけ抑えつつGroongaを使えるようにするためのライブラリーがあります。それがgroonga-client-modelです。groonga-client-modelがGroongaを使う部分の多くをフォローしてくれるため利用者は学習コストを抑えたままGroongaを使って高速な日本語全文検索システムを実現できます。実現する方法を説明します。実際にドキュメント検索システムを開発する手順を示すことで説明します。7を用いますが、他の環境でも同様の手順で実現できます。GroongaのインストールまずGroongaをインストールします。7以外の場合にどうすればよいかはGroongaのインストールドキュメントを参照してください。2.4をインストールします。Railsをインストールします。持ったドキュメント検索システムを開発します。newで雛形を作ります。Recordを一切使わないので--skip-active-recordを指定しています。gemをインストールします。install検索対象のドキュメントを格納するテーブルとそれを高速に検索するためのインデックスを定義します。定義はdb/schema.grnにGroongaのコマンドの書式で書きます。参考になるドキュメントは後で示すのでまずは実際の定義を確認しましょう。ドキュメントを格納するテーブル。ドキュメントのタイトルを格納するカラム。ドキュメントの内容を格納するカラム。全文検索インデックス用のテーブル。ドキュメントのタイトルと内容を全文検索するためのインデックス。Groongaではインデックスはカラムの一種。title,content以下は参考になるドキュメントです。作成したテーブル・インデックス定義はgroonga:schema:loadタスクでGroongaに取り込めます。groonga:schema:loadこれでGroongaに検索対象のドキュメントを格納するテーブルができたので対応するモデルを作ります。content:textこれでDocumentクラスがapp/models/document.rbに生成されます。Recordと同じような感じで使えます。動作を確認するためにQiitaから検索対象のドキュメントを取得するRakeタスクを作ります。endend実行して検索対象のドキュメントを作ります。data:load:qiitahttp://localhost:3000/documentsにアクセスし、データが入っていることを確認します。ビューにヒット件数表示機能と検索フォームをつけてコントローラーで全文検索するようにします。検索フォームではqueryというパラメーターに検索クエリーを指定することにします。@documentsを@requestに変更してビューで@request.responseとしているのは、コントローラーの時点ではまだGroongaにリクエストを発行せず、ビューで必要になった時点で発行するためです。Recordはto_aが必要になった時点で暗黙的に行っているのでユーザーが気にすることはありません。groonga-client-modelも同じようにすることができるのですが...長くなるので別の機会に説明します。)@request.responseとしている理由はもう1つあります。Recordで検索結果が違うからです。Recordはヒットしたモデルの配列を返しますが、groonga-client-modelはそれだけではなくさらに追加の情報も返します。「ヒット数」(@request.response.n_hits)も持っています。COUNT(*)を実行しないといけませんが、Groongaでは1回の検索で検索結果もヒット数も両方取得できるので効率的です。/documents/1この状態で次のようにレコード数とフォームが表示されるようになります。