#contents

*私家版:Ruby on Rails + Tritonnによるらくらく全文検索+KWIC表示のチュートリアル [#t23e699d]
*私家版:Ruby on Rails + Tritonnによるらくらく全文検索+KWIC表示のチュートリアル 02 August 2009[#t23e699d]

オリジナルのページは[[こちら>http://qwik.jp/tritonn/rortutorial.html]]

2009年7月6日((日本ショウジョウバエ研究会第9回研究集会の夕食のとき))、某大学の某氏((http://www.cis.kit.ac.jp/~tomaru/jdrc7registration.html に連名でプログラムを公開したりしています……、全然某じゃないか))にRubyはやってないのかと尋ねられ、
そのときは、~
そのときは、
 ブックマークはしているけどインストールしていない、最近はPerlばかり使ってて
と答えたのです((系統情報の整理にPerlをかなり使っていたのです))。~
が、インストールしてしまったのでした。~
そこで、素のMySQLではなく、全文検索のできるsennaが組み込まれたMySQLである[[Tritonn>http://qwik.jp/tritonn/]]と[[Ruby on Rails>http://rubyonrails.org/]]をインストールし、[[Ruby on Rails + Tritonnによるらくらく全文検索+KWIC表示のチュートリアル>http://qwik.jp/tritonn/rortutorial.html]]に従って動作確認をしようとしたところ、まったく動かなかったのです(7月20日のこと)。~
原因はRuby on Railsのバージョンが2であったこと。チュートリアルはRuby on Railsのバージョン1に対してのものでした。~

素のMySQLではなく、全文検索のできるsennaが組み込まれたMySQLである[[Tritonn>http://qwik.jp/tritonn/]]と、データベースの操作をするならこれからはこれ!の[[Ruby on Rails>http://rubyonrails.org/]]をインストールし、[[Ruby on Rails + Tritonnによるらくらく全文検索+KWIC表示のチュートリアル>http://qwik.jp/tritonn/rortutorial.html]]に従って動作確認をしようとしたところ、まったく動かなかったのです(7月20日のこと)。~
原因はRuby on Railsのバージョンが2であったこと。チュートリアルはRuby on Railsのバージョン1に対してのものでした(Last modified: 2009-03-23とありましたが。Ruby on Rails2は2007年12月にリリース)。~
そういった訳で、ほぼチュートリアルと同じ動作をする私家版を作らざるを得ず、作ったからには公開する次第です。7月中に公開できれば、6月はPerlやってたけど7月になったのでRubyにしたのさ、と言えたんですが((6月の誕生石が真珠、7月がルビー))、残念。

**著作権など [#r2115dc6]
http://qwik.jp/tritonn/rortutorial.html (Last modified: 2009-03-23)の著作権表示がいまひとつよくわからないのですが、元々の著作権はそのままです。追加訂正した部分はワタクシ。元々の著作権がGNU Free Documentation License (GFDL) ならば、このページもGFDL(このページだけでほかのページは違います)。TritonnがGPLなのでチュートリアルはGFDLかも知れません。Last modified: 2009-03-23 版には明示されてないようですが。

**バージョンなど [#i9926f9e]
- ruby 1.8.7 (2009-06-12 patchlevel 174) [i386-mswin32] (ActiveScriptRuby 1.8.7(p174) with-winsock2):http://arton.hp.infoseek.co.jp/indexj.html より入手
- Rails 2.3.2:http://rubyonrails.org/ より入手
- tritonn-1.0.12-mysql-5.0.67-win32.zip:http://sourceforge.jp/projects/tritonn/releases/ より入手。tritonnのページはhttp://qwik.jp/tritonn/。これは、
ウィンドウズ版を使いました。OSは Windows VISTA Business。

- ruby 1.8.7 (2009-06-12 patchlevel 174) [i386-mswin32] (ActiveScriptRuby 1.8.7(p174) with-winsock2): http://arton.hp.infoseek.co.jp/indexj.html より入手
- ruby gem 1.3.4: http://rubyforge.org/frs/?group_id=126 より入手
- Ruby on Rails 2.3.2: gemでインストール(たぶん http://rubyonrails.org/ より入手)
- tritonn-1.0.12-mysql-5.0.67-win32.zip: http://sourceforge.jp/projects/tritonn/releases/ より入手。tritonnのページはhttp://qwik.jp/tritonn/。これは、
mysql  Ver 14.12 Distrib 5.0.67, for Win32 (ia32) になる。

なお rubyの本家本元は、http://www.ruby-lang.org/
rubyの本家本元は、http://www.ruby-lang.org/~
なお、MySQL(Tritonn)はサーバプロセスとして起動しておかなければなりません

ruby、rails、tritonn は無事にインストールできていることとして、以下進んでください。項目はオリジナルに準じるよう試みてはいますが、Railsの大幅な変更に対応したので、かなり異なってしまったところもあります。
**0 Tritonnのセットアップ [#we9a3438]

★Tritonnのインストール
tritonn-1.0.12-mysql-5.0.67-win32.zipを解凍し、C:\mysqlに配置。

** 1 アプリケーションの生成から入力フォーム作成まで [#na60ff24]
***事前準備 [#bb33c82f]
Railsを開発するフォルダを決めます。 
    例:C:\Work
-環境変数PATHに"C:\mysql\bin"を追加。(マイコンピュータ→プロパティ→詳細設定→環境変数で設定)

***Rails アプリケーションの作成 [#n28d85a0]
-C:\my.iniに以下のように記述。「(これは必須ではないが、推奨)」とオリジナル版にはある。
 [mysqld]
 character-set-server=utf8
 skip-character-set-client-handshake

コマンドプロンプトを開きます。事前準備で用意したディレクトリで以下のコマンドを入力します。
-mysqldをサービスに登録。管理者権限で実行したコマンドプロンプトで
 cd C:\mysql\bin
 mysqld-nt.exe --install MySQL

    rails rordemo
-MySQLを起動。管理者権限で実行したコマンドプロンプトで
 net start MySQL

このコマンドを実行することで、自動にアプリケーションの一式が作られます。

***プロジェクト作成 [#n89018aa]
★rubyをインストール
実際は ActiveScriptRuby 1.8.7(p174) with-winsock2 をインストール~

-http://arton.hp.infoseek.co.jp/indexj.html からActiveRuby.msi をダウンロードし、ダブルクリック
-c:\ruby-1.8  にインストールする
-環境変数PATHに"C:\ruby-1.8l\bin"を追加。(マイコンピュータ→プロパティ→詳細設定→環境変数で設定) 。Windowsを再起動[10&13Mar2010追加]

★ruby gem をインストール

-http://rubyforge.org/frs/?group_id=126 からrubygems-1.3.4.zip
-zipファイルを展開
-管理者権限で実行したコマンドプロンプトで cd し、
 ruby setup.rb


★ruby on rails をインストール

引き続き、管理者権限で実行したコマンドプロンプトで
  gem install rails
時間が掛かる、10分以上[速いマシンなら速い10Mar2010]

//[よくわからないが……]
//  gem install mysql

★不具合?に対処[13Mar2010追加]

C:\mysql\bin\libmysql.dll を C:\ruby-1.8l\bin にコピー~
これをしないとデータベース作成時(rake db:create)にエラーが出る~
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-list/42378 による


ruby、rails、tritonn は無事にインストールできていることとして、以下進んでください。項目などはオリジナルに準じるよう試みてはいますが、Railsの大幅な変更に対応したので、かなり異なってしまったところもあります。



** 1 アプリケーションの生成から入力フォーム作成まで [#na60ff24]
***事前準備 [#bb33c82f]
Railsを開発するフォルダを決めます。 
    例:C:\Work
以下では、「○○」と示すことがあります。

***プロジェクト作成 [#n89018aa]
コマンドプロンプトで(管理者権限のコマンドプロンプトでなくてよい)~
プロジェクト「rordemo」を作成し、データベースにMySQLを設定する(デフォルトではsqlite3)
 cd ○○
 rails rordemo -d mysql

rordemoプロジェクトが作成される。フォルダやファイルが一気にできる。


***雛形作成 [#w7407c3a]
 cd rordemo
 ruby script/generate scaffold article content:text

rordemoプロジェクトの雛形が作成される。フォルダやファイルが一気にできる。

***テーブル作成 [#cf78c5a4]

○○/rordemo/db/migrate/○○_create_articles.rbを変更

 オリジナル
 《オリジナル》
 class CreateArticles < ActiveRecord::Migration
   def self.up
     create_table :articles do |t|
       t.text :content

 
       t.timestamps
     end
   end
 
   def self.down
     drop_table :articles
   end
 end

 変更後
- MySQLではストーレージエンジンがデフォルトでInnoDBになっているが、TritonnではMYISAMでなければならないそうなので、下のように変更する。http://info.dwango.co.jp/rd/2009/02/ruby-on-rails-mysql.html を参考にしました。

- フルテキストインデックスを作るために、SQL文を発行。ウィンドウズ版なので(また、ちょっとした下心もあるので)N-GRAMで分割するだけとする。

 《変更後》
 class CreateArticles < ActiveRecord::Migration
   def self.up
     create_table :articles, :options => "ENGINE = MYISAM" do |t|
       t.text :content
 
       t.timestamps
     end
     execute "ALTER TABLE articles change content content LONGTEXT"
     execute "ALTER TABLE articles add FULLTEXT INDEX USING NGRAM (content)"
   end
 
   def self.down
     drop_table :articles
   end
 end
※ 「execute "ALTER TABLE articles change content content LONGTEXT"」は、なくてもいいが、textは文字数が制限される
※ 「execute "ALTER TABLE articles change content content LONGTEXT"」は、なくてもいいが、textは文字数が制限される。MySQL 5 の[[リファレンスマニュアル>http://dev.mysql.com/doc/refman/5.0/en/storage-requirements.html]]によると
-- text: 2&super{16};未満 + 2 byte → 65535 + 2 ってことは、全角で32,767文字。改行とかタグとか考えると((下心はこういうところにある))ちょっと大きなウェブページは全然足りない。
-- longtext: 2&super{32};未満 + 4 byte → 4,294,967,295 + 4 ってことは、全角で2,147,483,647文字。21億文字(にじゅういちおく)。本1冊じゃなきゃ(でも?)これでだいたいはおっけいでしょう。

 rake db:create
 rake db:migrate

ruby script/generate controller Search
データベースの設定が完了 & 一番簡単な入力フォームの完成

ruby script/server
***サーバ起動 [#wb29b2d5]
 ruby script/server
(停止は Ctrl+c)


http://localhost:3000/Articles/
***ページの閲覧 [#d1e7267a]
 http://localhost:3000/Articles/
にアクセス

Listing articles
Content
 Listing articles
 Content
 
 New article

New article

が見えればおっけい

**1.5 おまけ [#uecc2681]

この「おまけ」の項目は単に記録であって、動かすためには何もしなくてよいものです。とはいえ、ちょっとは気になる点だと思いここに書いときます

***MySQLの権限 [#d5665dfe]
 MySQLのユーザ: root
 パスワード:  なし
これは、○○/rordemo/configdatabase.yml に自動で下のように作成されたものが設定されたため。~
必要に応じて書き換えること、と書くとチュートリアルふうかしら
 development:
   adapter: mysql
   encoding: utf8
   reconnect: false
   database: rordemo_development
   pool: 5
   username: root
   password:
   host: localhost

MySQLに接続
 mysql -
***MySQLにできるデータベースとテーブル [#xbb58ab7]
mysql> show tables; で二つテーブルが見える
 データベース: rordemo_development
 テーブル:   articles, schema_migrations
トラブルがあったらテーブルを二つとも drop してからやり直す。articles だけしか drop しないと上手くいかないことがある。

データベースを作成
***articles のフィールドなど [#b6686f34]
mysql> desc articles; の結果
|Field      | Type    | Null | Key | Default | Extra         |h
|id         |int(11)  |NO    |PRI  |NULL     |auto_increment |
|content    |longtext |YES   |MUL  |NULL     |               |
|created_at |datetime |YES   |     |NULL     |               |
|updated_at |datetime |YES   |     |NULL     |               |
-id は ○○_create_articles.rb に何も書かなくても自動で作られる
-t.text :content によって、content が作られる。さらに execute "ALTER TABLE articles change content content LONGTEXT" で longtext に変更もされている
-t.timestamps によって、created_at と updated_at が作られる

create database rordemo_development;
***インデックスなど [#ze7983a4]
mysql> show index from rordemo_development.articles; の結果
|Table     |Non_unique  |Key_name  |Seq_in_index  |Column_name |Collation |h
| articles |          0 | PRIMARY  |            1 | id          | A         |
| articles |          1 | content  |            1 | content     | NULL      |
  ~
|Cardinality |Sub_part |Packed |Null |Index_type |Comment |h
|           2 |     NULL | NULL   |      | BTREE      |         |
|        NULL |     NULL | NULL   | YES  | FULLTEXT   |         |
CENTER:※ 見やすさ優先のため、左右に長い表を分割しました
-フィールド content に対するフルテキストインデックスができていることがわかる

テーブルの作成  
**2 検索機能の追加 [#h0650229]
***ページの作成 [#f67ba107]
generate を利用して、検索を行うページを作成
 ruby script/generate controller Search

テーブルを作成し、以下に保存
***コントローラにメソッドを追加 [#t6cabea2]
○○/rordemo/app/controllers/search_controller.rb
にメソッドを追加

    [/rordemo/db/create.sql]
 《前》
 class SearchController < ApplicationController
 end

DROP TABLE IF EXISTS `articles`;
 《追加後》
 class SearchController < ApplicationController
   def index
   end
 
   def search_text
     @articles = Article.search_text(params[:query])
     flash.now[:notice] = "Search result#{@articles.size}found."
       render(:action => 'search_text')
   end
 end

CREATE TABLE `articles` (
  `id` int(11) NOT NULL auto_increment,
  `date` datetime NOT NULL default '2007-10-04 00:00:00',
  `content` longtext,
  PRIMARY KEY  (`id`),
  FULLTEXT KEY `ft` USING NGRAM (`content`)
) ENGINE=MyISAM;

作ったテーブルをDBに挿入
***モデルにメソッドを追加 [#y5c45b2f]
○○/rordemo/app/models/article.rb を以下のデータに変更

mysql rordemo_development <db/create.sql -u root -h localhost
 《前》
 class Article < ActiveRecord::Base
 end

Railsとデータベースの連携
 《追加後》
 class Article < ActiveRecord::Base
   def self.search_text(query)
 
   find_by_sql(["
   select updated_at, match(content) against (?) as score, 
   kwic(content, 150,3,1,'',' ... ', ?, '<span id=word>', '</span>') as snippet
   from articles where match(content) against(?) order by score desc limit 20", 
              "#{query}","#{query}", "#{query}"]) 
 
   end
 end

 次に、Railsからデータベースを参照できるようにします。
***ビューの作成と編集 [#ae4ed1c1]

    [rordemo/config/database.ymi]
○○/rordemo/app/views/search/search_text.html.erb を新規作成し、以下のように編集

このファイルの中の以下の部分に注目してください。
 <table cellpadding="5" cellspacing="0">
 
   <% for article in @articles %>
   <tr valign="top" class="catalogentry"> 
 
 <td align="left">
 <p>date <%=article.updated_at%><p>
 <p>score <%=article.score%><p>
 <p>snippet <%=article.snippet%><p>
 </td>
 
 </tr>
   <tr><td colspan="2"><div class="separator">&nbsp;</div></td></tr>
   <% end %>
 </table>

username: root
password:
host: localhost
○○/rordemo/app/views/search/index.html.erb
を新規作成し、以下のように編集。utf-8で保存

 この設定をを自分の環境に合わせて変更します。 今回はそのままで変更はありません。
 <p><label for="article_title"><b>検索</b></label></br>
 <% form_tag :action => "search_text", :method => "post" do  %>
 <%= text_field(:query,nil) -%><%= submit_tag "検索実行" %></p>
 <% end %>
 <br>
[ミスを修正14Mar2010]

development:
adapter: mysql
database: rordemo_development
username: root
password:
host: localhost
***共通レイアウトの設定 [#ke76ddd7]
雛形で作られたレイアウトを共通に使えるよう名前を変える

test:
adapter: mysql
database: rordemo_test
username: root
password:
host: localhost
○○/rordemo/app/views/layouts/articles.html.erb

 application.html.erb


production:
adapter: mysql
database: rordemo_production
username: root
password:
host: localhost

日本語の設定
***スタイルシートのカスタマイズ [#lb8d2cb4]
○○/rordemo/public/stylesheets/scaffold.css
(の末尾)にキーワードに対応したスタイルを追記

2箇所のファイルの書き換えを行います。
 #word {
   background-color: #faf
 }

    [config/enveronment.rb]
これで検索結果画面のキーワード部分に背景色がつく

に以下のコードを先頭に追加
***リンクの追加 [#k4e04ab0]

$KCODE="utf8"
ページ間の移動のためのリンクを追加。しなくても「全文検索+KWIC表示」できる

    [app/controllers/appllication.rb]

を以下のように変更。これにより、作成ファイル全てにutf8が適応されます。

class ApplicationController < ActionController::Base
 before_filter :set_charset
  private
  def set_charset
    headers["Content-Type"] = "text/html; charset=utf8"
  end
end

入力フォームの作成

generateを使用することで、簡単に入力フォームか作成されます。

    ruby script/generate scaffold Article Admin

作成されるファイルは以下のとおり。

      exists  app/controllers/
      exists  app/helpers/
      create  app/views/admin
      exists  app/views/layouts/
      exists  test/functional/
  dependency  model
      exists    app/models/
      exists    test/unit/
      exists    test/fixtures/
      create    app/models/article.rb
      create    test/unit/article_test.rb
      create    test/fixtures/articles.yml
      create  app/views/admin/_form.rhtml
      create  app/views/admin/list.rhtml
      create  app/views/admin/show.rhtml
      create  app/views/admin/new.rhtml
      create  app/views/admin/edit.rhtml
      create  app/controllers/admin_controller.rb
      create  test/functional/admin_controller_test.rb
      create  app/helpers/admin_helper.rb
      create  app/views/layouts/admin.rhtml
      create  public/stylesheets/scaffold.css

これで一番簡単な入力フォームの完成!
ページの閲覧
サーバ起動

これで一通りのパーツがそろいました。RailsにはWEBrickと呼ばれるwebサーバが同梱されていますので、それを利用してページが見られるか確認しましょう。

ruby script/server
=> Booting WEBrick...
=> Rails application started on http://0.0.0.0:3000
=> Ctrl-C to shutdown server; call with --help for options
[2007-10-03 17:40:29] INFO WEBrick 1.3.1
[2007-10-03 17:40:29] INFO ruby 1.8.6 (2007-09-23) [i386-mswin32]
[2007-10-03 17:40:29] INFO WEBrick::HTTPServer#start: pid=6108 port=3000

(停止は Ctrl+c)
ページの閲覧

    http://localhost:3000/admin

これで見られたら、第一段階が終了。

    注)これからファイルのページの更新を行いますが、そのたびにサーバは停止しておくのがよいでしょう。

2 検索機能の追加
ページのの作成

generate を利用して、検索を行うページを作成します。

    ruby script/generate controller Search index

以下のファイルが追加されます。

exists app/controllers/
exists app/helpers/
create app/views/search
exists test/functional/
create app/controllers/search_controller.rb
create test/functional/search_controller_test.rb
create app/helpers/search_helper.rb
create app/views/search/index.rhtml

Searchは作成するコントローラ名で、indexはSearchコントローラにindex()メソッドをひとつ持たせるという意味になります。ここで最初のメソッドにindexとつけた理由は、「http://localhost:3000/search/」と入力した場合に自動的にindexメソッドが呼び出されるからです。このようにRailsでは、コントローラを呼び出す際に明示的にアクションを指定していないと自動的にindex()アクションが呼び出されるようになっています。
ページの閲覧

再びWebrickサーバを起動し、以下にアクセス

    http://localhost:3000/search/

./rortutorial.files/search_index1.jpg

まだ雛形を作成しただけなのでこの様な画面がいればOK.
検索フォームの作成
追加すべきファイル
コントローラにメソッドを追加

    [app/controllers/search_controller.rb]

を以下のデータに変更します。

class SearchController < ApplicationController
#def index
# @articles = Article.items
#end
def search_text
@articles = Article.search_text(params[:query])
flash.now[:notice] = "Search result#{@articles.size}found."
render(:action => 'search_text')
end
end

モデルにメソッドを追加

    [app/models/article.rb]

を以下のデータに変更

class Article < ActiveRecord::Base
def self.search_text(query)

find_by_sql(["
select date, match(content) against (?) as score, 
kwic(content, 150,3,1,'',' ... ', ?, '<span id=word>', '</span>') as snippet
from articles where match(content) against(?) order by score desc limit 20", 
             "#{query}","#{query}", "#{query}"])
end
end

ビューの作成と編集

    [app/views/search/search_text.rhtml]

を新規作成し、以下のように編集。

<html>
<body>
<table cellpadding="5" cellspacing="0">

  <% for article in @articles %>
  <tr valign="top" class="catalogentry">

<td align="left">
<p>date <%=article.date%><p>
<p>score <%=article.score%><p>
<p>snippet <%=article.snippet%><p>
</td>

</tr>
  <tr><td colspan="2"><div class="separator">&nbsp;</div></td></tr>
  <% end %>
</table>
</body>
</html>

    [app/views/search/index.rhtml]

を以下のデータに変更する。

<html>
<body>
<p><label for="article_title"><b>検索</b></label></br>
<%= form_tag(:action => :search_text) %>
<%= text_field(:query,nil) -%><%= submit_tag "検索実行" %></p>
<%= end_form_tag %>
<br>
</body>
</html>

ページの閲覧

再びWebrickサーバを起動し、以下にアクセス

    http://localhost:3000/search/

./rortutorial.files/search_image.jpg

これで検索ページが表示されれば成功!
search_image.jpg
search_image.jpg
download
スタイルシートのカスタマイズ

    [app/views/search/search_text.rhtml]

を編集し、検索結果ページにスタイルシートを適用するように設定しましょう。

<head>
<link href="/stylesheets/scaffold.css" media="all" rel="Stylesheet" type="text/css" />
</head>

    [public/stylesheets/scaffold.css]

にキーワードに対応したスタイルを追記します。

#word {
  background-color: #faf
}

これで検索結果画面のキーワード部分に背景色がつきます。
リンクの追加

後は好みでリンクを追加すると良いかもしれません。

今のままだとページ間の移動がしにくいパタンがあるのでリンクをいくつか追加します。

    [app/views/search/search_text.rhtml]

-○○/rordemo/app/views/search/search_text.html.erb
ページ先頭に以下の一行を追加。

<%= link_to 'Back', :action => '' %>

 <%= link_to 'Back', :action => '' %>
これで検索結果画面から、検索画面へ戻れるようになります。

    [app/views/search/index.rhtml]

ページ末尾に以下の一行を追加。

<a href="../admin/">閲覧/登録</a>

-○○/rordemo/app/views/search/index.html.erb
ページ末尾に以下の一行を追加。utf-8で保存
 <a href="../articles/">閲覧/登録</a>
これで検索画面から、記事登録/閲覧画面へ飛べるようになります。

    [app/views/admin/list.rhtml]

ページ末尾に以下の一行を追加。

<br /><a href="../search">検索</a>

-○○/rordemo/app/views/articles/index.html.erb
ページ末尾に以下の一行を追加。utf-8で保存
 <br /><a href="../search">検索</a>
これで記事登録/閲覧画面から検索画面に飛べるようになります。








|Today:&counter(today);|Yesterday:&counter(yesterday);|Total:&counter(); since 2 August 2009|


トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS