rroonga 0.9.4-x86-mingw32 → 0.9.5-x86-mingw32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (153) hide show
  1. data/NEWS.ja.rdoc +29 -0
  2. data/NEWS.rdoc +29 -0
  3. data/Rakefile +6 -6
  4. data/ext/groonga/rb-grn-array.c +1 -1
  5. data/ext/groonga/rb-grn-context.c +15 -28
  6. data/ext/groonga/rb-grn-exception.c +46 -1
  7. data/ext/groonga/rb-grn-expression.c +22 -13
  8. data/ext/groonga/rb-grn-fix-size-column.c +2 -8
  9. data/ext/groonga/rb-grn-hash.c +8 -1
  10. data/ext/groonga/rb-grn-object.c +1 -1
  11. data/ext/groonga/rb-grn-patricia-trie.c +23 -1
  12. data/ext/groonga/rb-grn-table-key-support.c +22 -0
  13. data/ext/groonga/rb-grn-table.c +37 -5
  14. data/ext/groonga/rb-grn-utils.c +20 -2
  15. data/ext/groonga/rb-grn.h +1 -1
  16. data/ext/groonga/rb-groonga.c +76 -38
  17. data/extconf.rb +17 -1
  18. data/html/developer.html +32 -7
  19. data/html/footer.html.erb +5 -0
  20. data/html/heading-mark.svg +393 -0
  21. data/html/index.html +33 -3
  22. data/lib/1.8/groonga.so +0 -0
  23. data/lib/1.9/groonga.so +0 -0
  24. data/lib/groonga.rb +3 -7
  25. data/lib/groonga/context.rb +2 -13
  26. data/lib/groonga/expression-builder.rb +273 -67
  27. data/lib/groonga/pagination.rb +143 -0
  28. data/lib/groonga/record.rb +2 -0
  29. data/lib/groonga/schema.rb +140 -29
  30. data/pkg/rroonga-0.9.5/NEWS.ja.rdoc +156 -0
  31. data/pkg/rroonga-0.9.5/NEWS.rdoc +158 -0
  32. data/pkg/rroonga-0.9.5/README.ja.rdoc +65 -0
  33. data/pkg/rroonga-0.9.5/README.rdoc +66 -0
  34. data/pkg/rroonga-0.9.5/text/TUTORIAL.ja.rdoc +394 -0
  35. data/pkg/rroonga-0.9.5/text/expression.rdoc +285 -0
  36. data/rroonga-build.rb +2 -2
  37. data/test-unit/Rakefile +40 -0
  38. data/test-unit/TODO +5 -0
  39. data/test-unit/bin/testrb +5 -0
  40. data/test-unit/html/classic.html +15 -0
  41. data/test-unit/html/index.html +25 -0
  42. data/test-unit/html/index.html.ja +27 -0
  43. data/test-unit/lib/test/unit.rb +323 -0
  44. data/test-unit/lib/test/unit/assertionfailederror.rb +25 -0
  45. data/test-unit/lib/test/unit/assertions.rb +1230 -0
  46. data/test-unit/lib/test/unit/attribute.rb +125 -0
  47. data/test-unit/lib/test/unit/autorunner.rb +360 -0
  48. data/test-unit/lib/test/unit/collector.rb +36 -0
  49. data/test-unit/lib/test/unit/collector/descendant.rb +23 -0
  50. data/test-unit/lib/test/unit/collector/dir.rb +108 -0
  51. data/test-unit/lib/test/unit/collector/load.rb +144 -0
  52. data/test-unit/lib/test/unit/collector/objectspace.rb +34 -0
  53. data/test-unit/lib/test/unit/color-scheme.rb +102 -0
  54. data/test-unit/lib/test/unit/color.rb +96 -0
  55. data/test-unit/lib/test/unit/diff.rb +724 -0
  56. data/test-unit/lib/test/unit/error.rb +130 -0
  57. data/test-unit/lib/test/unit/exceptionhandler.rb +39 -0
  58. data/test-unit/lib/test/unit/failure.rb +136 -0
  59. data/test-unit/lib/test/unit/fixture.rb +176 -0
  60. data/test-unit/lib/test/unit/notification.rb +129 -0
  61. data/test-unit/lib/test/unit/omission.rb +191 -0
  62. data/test-unit/lib/test/unit/pending.rb +150 -0
  63. data/test-unit/lib/test/unit/priority.rb +180 -0
  64. data/test-unit/lib/test/unit/runner/console.rb +52 -0
  65. data/test-unit/lib/test/unit/runner/emacs.rb +8 -0
  66. data/test-unit/lib/test/unit/runner/tap.rb +8 -0
  67. data/test-unit/lib/test/unit/testcase.rb +476 -0
  68. data/test-unit/lib/test/unit/testresult.rb +89 -0
  69. data/test-unit/lib/test/unit/testsuite.rb +110 -0
  70. data/test-unit/lib/test/unit/ui/console/outputlevel.rb +14 -0
  71. data/test-unit/lib/test/unit/ui/console/testrunner.rb +466 -0
  72. data/test-unit/lib/test/unit/ui/emacs/testrunner.rb +63 -0
  73. data/test-unit/lib/test/unit/ui/tap/testrunner.rb +92 -0
  74. data/test-unit/lib/test/unit/ui/testrunner.rb +28 -0
  75. data/test-unit/lib/test/unit/ui/testrunnermediator.rb +77 -0
  76. data/test-unit/lib/test/unit/ui/testrunnerutilities.rb +41 -0
  77. data/test-unit/lib/test/unit/util/backtracefilter.rb +41 -0
  78. data/test-unit/lib/test/unit/util/method-owner-finder.rb +28 -0
  79. data/test-unit/lib/test/unit/util/observable.rb +90 -0
  80. data/test-unit/lib/test/unit/util/procwrapper.rb +48 -0
  81. data/test-unit/lib/test/unit/version.rb +7 -0
  82. data/test-unit/sample/adder.rb +13 -0
  83. data/test-unit/sample/subtracter.rb +12 -0
  84. data/test-unit/sample/test_adder.rb +20 -0
  85. data/test-unit/sample/test_subtracter.rb +20 -0
  86. data/test-unit/sample/test_user.rb +23 -0
  87. data/test-unit/test/collector/test-descendant.rb +133 -0
  88. data/test-unit/test/collector/test-load.rb +442 -0
  89. data/test-unit/test/collector/test_dir.rb +406 -0
  90. data/test-unit/test/collector/test_objectspace.rb +100 -0
  91. data/test-unit/test/run-test.rb +15 -0
  92. data/test-unit/test/test-attribute.rb +86 -0
  93. data/test-unit/test/test-color-scheme.rb +67 -0
  94. data/test-unit/test/test-color.rb +47 -0
  95. data/test-unit/test/test-diff.rb +518 -0
  96. data/test-unit/test/test-emacs-runner.rb +60 -0
  97. data/test-unit/test/test-fixture.rb +287 -0
  98. data/test-unit/test/test-notification.rb +33 -0
  99. data/test-unit/test/test-omission.rb +81 -0
  100. data/test-unit/test/test-pending.rb +70 -0
  101. data/test-unit/test/test-priority.rb +119 -0
  102. data/test-unit/test/test-testcase.rb +544 -0
  103. data/test-unit/test/test_assertions.rb +1151 -0
  104. data/test-unit/test/test_error.rb +26 -0
  105. data/test-unit/test/test_failure.rb +33 -0
  106. data/test-unit/test/test_testresult.rb +113 -0
  107. data/test-unit/test/test_testsuite.rb +129 -0
  108. data/test-unit/test/testunit-test-util.rb +14 -0
  109. data/test-unit/test/ui/test_testrunmediator.rb +20 -0
  110. data/test-unit/test/util/test-method-owner-finder.rb +38 -0
  111. data/test-unit/test/util/test_backtracefilter.rb +41 -0
  112. data/test-unit/test/util/test_observable.rb +102 -0
  113. data/test-unit/test/util/test_procwrapper.rb +36 -0
  114. data/test/groonga-test-utils.rb +3 -2
  115. data/test/run-test.rb +14 -2
  116. data/test/test-column.rb +7 -7
  117. data/test/test-context-select.rb +34 -11
  118. data/test/test-exception.rb +3 -0
  119. data/test/test-expression-builder.rb +11 -0
  120. data/test/test-expression.rb +3 -6
  121. data/test/test-gqtp.rb +3 -5
  122. data/test/test-pagination.rb +249 -0
  123. data/test/test-record.rb +36 -8
  124. data/test/test-remote.rb +11 -4
  125. data/test/test-schema-create-table.rb +251 -0
  126. data/test/test-schema.rb +4 -24
  127. data/test/test-table-offset-and-limit.rb +3 -5
  128. data/test/test-table-select-mecab.rb +80 -0
  129. data/test/test-table-select-weight.rb +104 -0
  130. data/test/test-table.rb +22 -4
  131. data/test/test-version.rb +1 -1
  132. data/text/TUTORIAL.ja.rdoc +2 -0
  133. data/text/expression.rdoc +1 -0
  134. data/vendor/local/bin/grntest.exe +0 -0
  135. data/vendor/local/bin/groonga.exe +0 -0
  136. data/vendor/local/bin/libgroonga-0.dll +0 -0
  137. data/vendor/local/include/{groonga.h → groonga/groonga.h} +93 -32
  138. data/vendor/local/lib/groonga/modules/functions/cast.dll +0 -0
  139. data/vendor/local/lib/groonga/modules/functions/cast.la +41 -0
  140. data/vendor/local/lib/pkgconfig/groonga.pc +12 -0
  141. data/vendor/local/share/groonga/admin_html/css/admin.css +104 -0
  142. data/vendor/local/share/groonga/admin_html/css/ui-lightness/jquery-ui-1.8.1.custom.css +486 -0
  143. data/vendor/local/share/groonga/admin_html/index.html +1355 -0
  144. data/vendor/local/share/groonga/admin_html/js/jquery-1.4.2.min.js +154 -0
  145. data/vendor/local/share/groonga/admin_html/js/jquery-ui-1.8.1.custom.min.js +756 -0
  146. data/vendor/local/share/groonga/munin/plugins/groonga_cpu_load +47 -0
  147. data/vendor/local/share/groonga/munin/plugins/groonga_cpu_time +57 -0
  148. data/vendor/local/share/groonga/munin/plugins/groonga_disk +162 -0
  149. data/vendor/local/share/groonga/munin/plugins/groonga_memory +51 -0
  150. data/vendor/local/share/groonga/munin/plugins/groonga_n_records +110 -0
  151. data/vendor/local/share/groonga/munin/plugins/groonga_query_performance +133 -0
  152. data/vendor/local/share/groonga/munin/plugins/groonga_status +84 -0
  153. metadata +126 -36
@@ -0,0 +1,158 @@
1
+ = NEWS
2
+
3
+ == 0.9.5: 2010-07-20
4
+
5
+ * Supported groonga 0.7.4.
6
+ * Imporoved Groonga::Table#select:
7
+ * Supported weight match:
8
+
9
+ Here is an example to match source column or title column and
10
+ title column has high score:
11
+ table.select do |record|
12
+ (record.title * 10 | record.source) =~ "query"
13
+ end
14
+ * Supported and representation for and conditions:
15
+
16
+ Here are examples that represents the same condition:
17
+ table.select do |record|
18
+ conditions = []
19
+ conditions << record.title =~ "query"
20
+ conditions << record.updated_at > Time.parse("2010-07-29T21:14:29+09:00")
21
+ conditions
22
+ end
23
+
24
+ table.select do |record|
25
+ (record.title =~ "query") &
26
+ (record.updated_at > Time.parse("2010-07-29T21:14:29+09:00"))
27
+ end
28
+ * Provided groonga runtime version: Groonga::VERSION
29
+ * Added Groonga::Table#support_sub_records?
30
+ * Supported pagination: Groonga::Table#paginate, Groonga::Pagination
31
+
32
+ == 0.9.4: 2010-04-22
33
+
34
+ * Fixed release miss.
35
+
36
+ == 0.9.3: 2010-04-22
37
+
38
+ * Fixed release miss.
39
+
40
+ == 0.9.2: 2010-04-22
41
+
42
+ * Supported groonga 0.1.9.
43
+ * Many.
44
+
45
+ == 0.9.1: 2010-02-09
46
+
47
+ * Supported groonga 0.1.6
48
+
49
+ == 0.9.0: 2010-02-09
50
+
51
+ * Supported groonga 0.1.5
52
+ * Added API
53
+ * Groonga::Object#context
54
+ * Groonga::Record#n_sub_records
55
+ * Groonga::Context#send
56
+ * Groonga::Context#receive
57
+ * Groonga::PatriciaTrie#prefix_search [Tasuku SUENAGA]
58
+ * Groonga::Object#path [Ryo Onodera]
59
+ * Groonga::Object#lock [Tasuku SUENAGA]
60
+ * Groonga::Object#unlock [Tasuku SUENAGA]
61
+ * Groonga::Object#locked? [Tasuku SUENAGA]
62
+ * Groonga::Object#temporary?
63
+ * Groonga::Object#persistent?
64
+ * Groonga::ObjectClosed
65
+ * Groonga::Context.[]
66
+ * Groonga::Table#column_value
67
+ * Groonga::Table#set_column_value
68
+ * Changed API
69
+ * Groonga::Table#select, Groonga::Column#select
70
+ * They also accept Groonga::Expression
71
+ * Added :syntax option that specifies grn expression syntax
72
+ * Groonga::Table#open_cursor
73
+ * Added :offset option that specifies offset.
74
+ * Added :limit option that specifies max number of records.
75
+ * Changed Groonga::Expression.parse options:
76
+ * (nil (default) -> :column) -> (nil (default) -> :query)
77
+ * :column -> removed
78
+ * :table -> :query
79
+ * :table_query -> :query
80
+ * :expression -> :script
81
+ * :language -> :script
82
+ * Groonga::Table#define_column, Groonga::Table#define_index_column
83
+ * Defined column becomes persistent table by default
84
+ * Groonga::Table#[] -> Groonga::Table#value
85
+ * Groonga::Table#[]= -> Groonga::Table#set_value
86
+ * Groonga::Table#find -> Groonga::Table#[]
87
+ * Groonga::Table#find -> obsolete
88
+ * Groonga::Table#[]= -> removed
89
+ * Groonga::TableKeySupport#[]= is alias of Groonga::TableKeySupport#add
90
+ * Changed exception class to Groonga::NoSuchColumn from
91
+ Groonga::InvalidArgument when Groonga::Record accesses nonexistent
92
+ a column.
93
+ * Bug fixes
94
+ * Fixed a bug that context isn't passed to schema [dara]
95
+ * Fixed a bug that Groonga::PatriciaTrie#tag_keys doesn't return
96
+ that last text.
97
+ [Ryo Onodera]
98
+ * Added --with-debug option to extconf.rb for debug build.
99
+ * Fixed a bug that Ruby 1.9.1 may fail extconf.rb.
100
+
101
+ === Thanks
102
+
103
+ * dara
104
+ * Ryo Onodera
105
+ * Tasuku SUENAGA
106
+
107
+ == 0.0.7: 2009-10-02
108
+
109
+ * Supported groonga 0.1.4
110
+ * Added API
111
+ * Groonga::PatriciaTrie#scan
112
+ * Groonga::PatriciaTrie#tag_keys
113
+ * Groonga::Expression#snippet
114
+ * Groonga::Object#append
115
+ * Groonga::Object#prepend
116
+
117
+ == 0.0.6: 2009-07-31
118
+
119
+ * Supported groonga 0.1.1.
120
+ * Fixed documents [id:mat_aki]
121
+ * Supported groonga expression for searching.
122
+ * Added API
123
+ * Groonga::Table#union!
124
+ * Groonga::Table#intersect!
125
+ * Groonga::Table#differene!
126
+ * Groonga::Table#merge!
127
+ * Provided tar.gz [id:m_seki]
128
+ * Fixed memory leaks
129
+
130
+ == 0.0.3: 2009-07-18
131
+
132
+ * [#26145] Added Groonga::TableKeySupport#has_key? [Tasuku SUENAGA]
133
+ * [#26146] Groonga::Record#[] raises an exception for nonexistent
134
+ column name. [Tasuku SUENAGA]
135
+ * Supported 32bit environment [niku]
136
+ * Added a test for N-gram index search [dara]
137
+ * Added APIs
138
+ * Groonga::Record#incemrent!
139
+ * Groonga::Record#decemrent!
140
+ * Groonga::Record#lock
141
+ * Groonga::Table#lock
142
+ * Groonga::Schema: A DSL for schema definition
143
+ * Groonga::Expression
144
+
145
+ == 0.0.2: 2009-06-04
146
+
147
+ * Supported groonga 0.0.8 [mori]
148
+ * Improved preformance: cache key, value, domain and range
149
+ * Improved API
150
+ * Added documents
151
+ * Supported Ruby 1.9
152
+ * Bug fixes:
153
+ * Fixed install process [Tasuku SUENAGA]
154
+ * Fixed memory leaks
155
+
156
+ == 0.0.1: 2009-04-30
157
+
158
+ * Initial release!
@@ -0,0 +1,65 @@
1
+ = はじめに
2
+
3
+ == 名前
4
+
5
+ rroonga
6
+
7
+ == 説明
8
+
9
+ 全文検索機能とカラムストア機能を提供するgroongaのRubyバイン
10
+ ディングです。
11
+
12
+ groongaのいわゆるDB-API層をRubyから使うための拡張ライブラリで
13
+ す。groongaのAPIをそのままRubyレベルに提供するのではなく、
14
+ Rubyらしく読み書きしやすいAPIとして提供します。高速・高機能な
15
+ groongaをRubyらしい書き方で利用できます。
16
+
17
+ groongaに関する情報は以下を参照して下さい。
18
+
19
+ * groonga: http://groonga.org/
20
+
21
+ == 作者
22
+
23
+ Kouhei Sutou:: <tt><kou@clear-code.com></tt>
24
+ Tasuku SUENAGA:: <tt><a@razil.jp></tt>
25
+ daijiro:: <tt><morita@razil.jp></tt>
26
+ Yuto HAYAMIZU:: <tt><y.hayamizu@gmail.com></tt>
27
+ SHIDARA Yoji:: <tt><dara@shidara.net></tt>
28
+
29
+ == ライセンス
30
+
31
+ LGPL 2.1です。詳しくはlicense/LGPLを見てください。
32
+
33
+ pkg-config.rbはrcairoに付属しているもので、これはRubyライセ
34
+ ンスです。詳しくはlicense/RUBYとlicense/GPLを見てください。
35
+
36
+ == 依存ソフトウェア
37
+
38
+ * Ruby >= 1.8 (1.9.1対応)
39
+ * groonga >= 0.1.9
40
+
41
+ == インストール
42
+
43
+ % sudo gem install rroonga
44
+
45
+ == ドキュメント
46
+
47
+ http://groonga.rubyforge.org/rroonga/
48
+
49
+ == メーリングリスト
50
+
51
+ 質問、要望、バグ報告などはgroongaのMLにお願いします。
52
+
53
+ http://lists.sourceforge.jp/mailman/listinfo/groonga-dev
54
+
55
+ == 感謝
56
+
57
+ * 森さん: 最新groonga対応パッチをくれました。
58
+ * グニャラくん: バグレポートしてくれました。
59
+ * にくさん: バグレポートしてくれました。
60
+ * daraさん:
61
+ * テストを書いてくれました。
62
+ * バグを直してくれました。
63
+ * id:mat_akiさん: チュートリアルのバグを教えてくれました。
64
+ * @yune_kotomi: バグレポートしてくれました。
65
+ * 咳さん: バグレポートしてくれました。
@@ -0,0 +1,66 @@
1
+ = README
2
+
3
+ == Name
4
+
5
+ rroonga
6
+
7
+ == Description
8
+
9
+ Ruby bindings for groonga that provides full text search and
10
+ column store features.
11
+
12
+ rroonga is a extension library to use groonga's DB-API
13
+ layer. rroonga provides Rubyish readable and writable
14
+ API. You can use groonga's first and highly functional
15
+ features from Ruby.
16
+
17
+ See the following URL about groonga.
18
+
19
+ * groonga: http://groonga.org/
20
+
21
+ == Authors
22
+
23
+ Kouhei Sutou:: <tt><kou@clear-code.com></tt>
24
+ Tasuku SUENAGA:: <tt><a@razil.jp></tt>
25
+ daijiro:: <tt><morita@razil.jp></tt>
26
+ Yuto HAYAMIZU:: <tt><y.hayamizu@gmail.com></tt>
27
+ SHIDARA Yoji:: <tt><dara@shidara.net></tt>
28
+
29
+ == License
30
+
31
+ LGPL 2.1. See license/LGPL for details.
32
+
33
+ pkg-config.rb is a library that is bundled with rcairo. It's
34
+ distributed under Ruby license. See license/RUBY and
35
+ license/GPL for details.
36
+
37
+ == Dependencies
38
+
39
+ * Ruby >= 1.8 (including 1.9.1)
40
+ * groonga >= 0.1.9
41
+
42
+ == Install
43
+
44
+ % sudo gem install rroonga
45
+
46
+ == Documents
47
+
48
+ Japanese only. Sorry.
49
+
50
+ http://groonga.rubyforge.org/rroonga/
51
+
52
+ == Mailing list
53
+
54
+ http://rubyforge.org/mailman/listinfo/groonga-users-en
55
+
56
+ == Thanks
57
+
58
+ * mori: sent patches to support the latest groonga.
59
+ * Tasuku SUENAGA: sent bug reports.
60
+ * niku: sent bug reports.
61
+ * dara:
62
+ * wrote tests.
63
+ * fixed bugs.
64
+ * id:mat_aki: sent bug reports.
65
+ * @yune_kotomi: sent a bug report.
66
+ * m_seki: sent bug reports.
@@ -0,0 +1,394 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ = チュートリアル
4
+
5
+ このページでは簡単なアプリケーションの作成を通して
6
+ rroongaの操作方法を紹介します。
7
+
8
+ == インストール
9
+
10
+ Ruby/groongaはRubyGemsでインストールできます。
11
+
12
+ % sudo gem install rroonga
13
+
14
+ == データベースの作成
15
+
16
+ 簡単なブックマークアプリケーション用のデータベースを作ってみ
17
+ ます。以下のようにgroongaライブラリを読み込んでirbを起動しま
18
+ す。
19
+
20
+ % irb --simple-prompt -rubygems -rgroonga
21
+ >>
22
+
23
+ まず、エンコーディングを設定します。ここではUTF-8を利用します。
24
+
25
+ >> $KCODE = "UTF-8"
26
+ => "UTF-8"
27
+ >> Groonga::Context.default_options = {:encoding => :utf8}
28
+ => {:encoding=>:utf8}
29
+
30
+ それでは、ファイルを指定してデータベースを作成します。
31
+
32
+ >> Groonga::Database.create(:path => "/tmp/bookmark.db")
33
+ => #<Groonga::Database ...>
34
+
35
+ ここで作成したデータベースは、これ以降、暗黙のうちに利用され
36
+ ます。最初にデータベースを作成したら特に意識する必要はありま
37
+ せん。
38
+
39
+ == テーブルの定義
40
+
41
+ groongaには以下の3種類のテーブルがあります。
42
+
43
+ [Groonga::Hash]
44
+ ハッシュテーブル。主キーでレコードを管理します。キーと完全
45
+ 一致するレコードを非常に高速に検索することができます。
46
+ [Groonga::PatriciaTrie]
47
+ パトリシアトライ。ハッシュテーブルに比べて完全一致検索の速
48
+ 度がやや遅いですが、前方一致検索・共通接頭辞探索などの検索
49
+ が行えます。またカーソルを用いてキーの昇降順にレコードを取
50
+ り出すことができます。
51
+ [Groonga::Array]
52
+ 配列。主キーの存在しないテーブルです。レコードはIDによって
53
+ 識別します。
54
+
55
+ ここではハッシュテーブルを利用して、<tt>Items</tt>という名前のテー
56
+ ブルを作成します。キーは文字列とします。
57
+
58
+ >> items = Groonga::Hash.create(:name => "Items", :key_type => "ShortText")
59
+ => #<Groonga::Hash ...>
60
+
61
+
62
+ これで<tt>Items</tt>という名前のテーブルが作成できました。
63
+
64
+ テーブルはRubyのHashのように扱えます。
65
+
66
+ 例えば、以下のように+size+でテーブルに登録されているレコード
67
+ の件数を取得できます。
68
+
69
+ >> items.size
70
+ 0
71
+
72
+ == レコードを追加する
73
+
74
+ <tt>Items</tt>テーブルにレコードを追加します。
75
+
76
+ >> items.add("http://ja.wikipedia.org/wiki/Ruby")
77
+ => #<Groonga::Record ...>
78
+ >> items.add("http://www.ruby-lang.org/")
79
+ => #<Groonga::Record ...>
80
+
81
+ 件数を確認すると確かに2件増えています。
82
+
83
+ >> items.size
84
+ => 2
85
+
86
+ 主キーを指定してレコードを取り出す時には以下のようにします。
87
+
88
+ >> items.find("http://ja.wikipedia.org/wiki/Ruby")
89
+ => #<Groonga::Record ...>
90
+
91
+ == 全文検索を行う
92
+
93
+ 各itemのタイトル文字列を登録して、全文検索できるようにしてみ
94
+ ましょう。
95
+
96
+ まず<tt>Items</tt>テーブルに+title+という名前のカラムを追加します。
97
+
98
+ >> title_column = items.define_column("title", "Text")
99
+ => #<Groonga::VarSizeColumn ...>
100
+
101
+ 2番目の引数は、追加するカラムのデータ型を示しています。
102
+ <tt><int></tt>、<tt>Text</tt>、<tt><longtext></tt>等の型が基本型として用意されて
103
+ います。
104
+
105
+ 全文検索するためには、文字列を分解して得られる各単語を格納す
106
+ るためのテーブルを別途しなければなりません。ここではTermsと
107
+ いう名前でテーブルを定義します。
108
+
109
+ >> terms = Groonga::Hash.create(:name => "Terms",
110
+ :key_type => "ShortText",
111
+ :default_tokenizer => "TokenBigram")
112
+ => #<Groonga::Hash ...>
113
+
114
+ ここでは、トークナイザとして<tt>:default_tokenzier =>
115
+ "TokenBigram"</tt> を指定しています。トークナイザとは文字
116
+ 列を単語に分解するオブジェクトのことです。デフォルトではトー
117
+ クナイザは指定されていません。全文検索を利用するためにはトー
118
+ クナイザを指定する必要があるので、ここではN-gramの一種である
119
+ バイグラムを指定しています。
120
+
121
+ N-gramを利用した全文検索では、分解したN文字とその出現位置を利
122
+ 用して全文検索を行います。N-gramのNは文字列を何文字毎に分解す
123
+ るかの文字数になります。groongaは1文字で分解するユニグラム、
124
+ 2文字のバイグラム、3文字のトリグラムをサポートしています。
125
+
126
+ 単語格納用テーブルの準備ができたので、<tt>Items</tt>テーブ
127
+ ルの+title+カラムに対するインデックスを定義します。
128
+
129
+ >> title_index_column = terms.define_index_column("item_title", items,
130
+ :source => "Items.title")
131
+ => #<Groonga::IndexColumn ...>
132
+
133
+ 少し違和感を感じるかも知れませんが、<tt>Items</tt>テーブル
134
+ のカラムに対するインデックスは、<tt>Terms</tt>テーブルのカ
135
+ ラムとして定義します。
136
+
137
+ <tt>Items</tt>にレコードが登録されると、その中に含まれる単
138
+ 語に該当するレコードが<tt>Terms</tt>に自動的に追加されるよ
139
+ うになります。
140
+
141
+ <tt>Terms</tt>は、文書に含まれる語彙に相当する、やや特殊な
142
+ テーブルだと言えます。しかし、他のテーブルと同様に語彙テーブ
143
+ ルには自由にカラムを追加し、単語毎の様々な属性を管理すること
144
+ ができます。これはある種の検索処理を行う際には非常に便利に機
145
+ 能します。
146
+
147
+ これでテーブルの定義は完了です。
148
+
149
+ 先ほど登録した各レコードの+title+カラムに値をセットします。
150
+
151
+ >> items.find("http://ja.wikipedia.org/wiki/Ruby")["title"] = "Ruby"
152
+ => "Ruby"
153
+ >> items.find("http://www.ruby-lang.org/")["title"] = "オブジェクトスクリプト言語Ruby"
154
+ "オブジェクトスクリプト言語Ruby"
155
+
156
+ 以下のようにして検索することができます。
157
+
158
+ >> title_index_column.search("Ruby").collect {|record| record.key.key}
159
+ ["http://ja.wikipedia.org/wiki/Ruby", "http://www.ruby-lang.org/"]
160
+
161
+ 検索結果はGroonga::Hashで返されます。ハッシュのキーに見つかっ
162
+ た<tt>Items</tt>のレコードが入っています。上の例では
163
+ +record.key+で<tt>Items</tt>のレコードを取得して、さらにそ
164
+ のキーを指定して(+record.key.key+)で<tt>Items</tt>のキー
165
+ を返しています。
166
+
167
+
168
+ == マルチユーザ向けのブックマークアプリケーション
169
+
170
+ ここまでで作った単機能のアプリケーションをもう少し拡張して、
171
+ 複数のユーザが、それぞれにコメントを記入できるブックマークア
172
+ プリケーションにしてみましょう。
173
+
174
+ まず、ユーザ情報とコメント情報を格納するテーブルを追加して、
175
+ 下図のようなテーブル構成にします。
176
+
177
+ http://qwik.jp/senna/senna2.files/rect4605.png
178
+
179
+ まず、<tt>Users</tt>テーブルを追加します。
180
+
181
+ >> users = Groonga::Hash.create(:name => "Users",
182
+ :key_type => "ShortText")
183
+ => #<Groonga::Hash ...>
184
+ >> users.define_column("name", "Text")
185
+ => #<Groonga::VarSizeColumn ...>
186
+
187
+
188
+ 次に、<tt>Comments</tt>テーブルを追加します。
189
+
190
+ >> comments = Groonga::Array.create(:name => "Comments")
191
+ => #<Groonga::Array ...>
192
+ >> comments.define_column("item", items)
193
+ => #<Groonga::FixSizeColumn ..>
194
+ >> comments.define_column("author", users)
195
+ => #<Groonga::FixSizeColumn ..>
196
+ >> comments.define_column("content", "Text")
197
+ => #<Groonga::VarSizeColumn ..>
198
+ >> comments.define_column("issued", "Time")
199
+ => #<Groonga::FixSizeColumn ..>
200
+
201
+ <tt>Comments</tt>テーブルの+content+カラムを全文検索できる
202
+ ようにインデックスを定義します。
203
+
204
+ >> terms.define_index_column("comment_content", comments,
205
+ :source => "Comments.content")
206
+ => #<Groonga::IndexColumn ...>
207
+
208
+ これでテーブルが定義できました。
209
+
210
+ 続いてユーザを何人か追加します。
211
+
212
+ >> users.add("moritan", :name => "モリタン")
213
+ => #<Groonga::Record ...>
214
+ >> users.add("taporobo", :name => "タポロボ")
215
+ => #<Groonga::Record ...>
216
+
217
+ 次に、実際にユーザがブックマークを貼る時の処理を実行してみま
218
+ しょう。
219
+
220
+ ユーザ+moritan+が、はてなダイアリーのとあるページをブックマーク
221
+ したと想定します。
222
+
223
+ まず対象のページが<tt>Items</tt>テーブルに登録済かどうか調
224
+ べます。
225
+
226
+ >> items.find("http://d.hatena.ne.jp/brazil/20050829/1125321936")
227
+ => nil
228
+
229
+ 未登録なのでまず当該ページを<tt>Items</tt>に登録します。
230
+
231
+ >> items.add("http://d.hatena.ne.jp/brazil/20050829/1125321936",
232
+ :title => "[翻訳]JavaScript: 世界で最も誤解されたプログラミング言語")
233
+ => #<Groonga::Record ...>
234
+
235
+ 次に、登録したitemを+item+カラムの値に指定して
236
+ <tt>Comments</tt>にレコードを登録します。
237
+
238
+ >> comments.add(:item => "http://d.hatena.ne.jp/brazil/20050829/1125321936",
239
+ :author => "moritan",
240
+ :content => "JavaScript LISP",
241
+ :issued => 1187430026)
242
+ => #<Groonga::Record ...>
243
+
244
+ == メソッド化
245
+
246
+ 上記の一連の手続きをメソッドにまとめてみます。
247
+
248
+ >> @items = items
249
+ >> @comments = comments
250
+ >> def add_bookmark(url, title, author, content, issued)
251
+ >> item = @items.find(url) || @items.add(url, :title => title)
252
+ >> @comments.add(:item => item,
253
+ >> :author => author,
254
+ >> :content => content,
255
+ >> :issued => issued)
256
+ >> end
257
+
258
+ +itmes+と+comments+をインスタンス変数に代入しているのはメソッ
259
+ ド内からでも見えるようにするためです。
260
+
261
+ +add_bookmark+は以下のような手順を実行しています。
262
+
263
+ * <tt>Items</tt>テーブルに該当ページのレコードがあるかどうか調べる。
264
+ * レコードがなければ追加する。
265
+ * <tt>Comments</tt>テーブルにレコードを登録する。
266
+
267
+ 作成したメソッドを呼び出していくつかブックマークを登録してみ
268
+ ましょう。
269
+
270
+ >> add_bookmark("http://practical-scheme.net/docs/cont-j.html",
271
+ "なんでも継続", "moritan", "継続 LISP Scheme", 1187568692)
272
+ => #<Groonga::Record ...>
273
+ >> add_bookmark("http://d.hatena.ne.jp/higepon/20070815/1187192864",
274
+ "末尾再帰", "taporobo", "末尾再帰 Scheme LISP", 1187568793)
275
+ => #<Groonga::Record ...>
276
+ >> add_bookmark("http://practical-scheme.net/docs/cont-j.html",
277
+ "なんでも継続", "taporobo", "トランポリン LISP continuation",
278
+ 1187568692)
279
+ => #<Groonga::Record ...>
280
+
281
+ == 全文検索その2
282
+
283
+ 登録したレコードに対して全文検索を実行してみます。
284
+
285
+ >> records = comments.select do |record|
286
+ >> record["content"] =~ "LISP"
287
+ >> end
288
+ >> records.each do |record|
289
+ >> record = record.key
290
+ >> p [record.id,
291
+ >> record[".issued"],
292
+ >> record[".item.title"],
293
+ >> record[".author.name"],
294
+ >> record[".content"]]
295
+ >> end
296
+ [1, Sat Aug 18 18:40:26 +0900 2007, "[翻訳]JavaScript: 世界で最も誤解されたプログラミング言語", "モリタン", "JavaScript LISP"]
297
+ [2, Mon Aug 20 09:11:32 +0900 2007, "なんでも継続", "モリタン", "継続 LISP Scheme"]
298
+ [3, Mon Aug 20 09:13:13 +0900 2007, "末尾再帰", "タポロボ", "末尾再帰 Scheme LISP"]
299
+ [4, Mon Aug 20 09:11:32 +0900 2007, "なんでも継続", "タポロボ", "トランポリン LISP continuation"]
300
+
301
+ カラムへのアクセスは、カラム名を+.+で繋いで複合データ型の要素
302
+ を再帰的に辿ることができます。(同様の出力を普通のRDBで実現す
303
+ るためには、<tt>Items</tt>テーブル、<tt>Comments</tt>テー
304
+ ブル、<tt>Users</tt>テーブルのJOIN操作が必要になります。)
305
+
306
+ 上の式の中で、肝心の検索処理は、第一引数の式を評価する時点で
307
+ 完了していて、レコードセットオブジェクトとしてメモリに蓄積さ
308
+ れています。
309
+
310
+ >> records
311
+ #<Groonga::Hash ..., size: <4>>
312
+
313
+ レコードセットは、出力する前に様々に加工することができます。
314
+
315
+ 以下は、日付で降順にソートしてから出力した例です。
316
+
317
+ >> records.sort([{:key => ".issued", :order => "descending"}]).each do |record|
318
+ >> record = record.key
319
+ >> p [record.id,
320
+ >> record[".issued"],
321
+ >> record[".item.title"],
322
+ >> record[".author.name"],
323
+ >> record[".content"]]
324
+ >> end
325
+ [3, Mon Aug 20 09:13:13 +0900 2007, "末尾再帰", "タポロボ", "末尾再帰 Scheme LISP"]
326
+ [2, Mon Aug 20 09:11:32 +0900 2007, "なんでも継続", "モリタン", "継続 LISP Scheme"]
327
+ [4, Mon Aug 20 09:11:32 +0900 2007, "なんでも継続", "タポロボ", "トランポリン LISP continuation"]
328
+ [1, Sat Aug 18 18:40:26 +0900 2007, "[翻訳]JavaScript: 世界で最も誤解されたプログラミング言語", "モリタン", "JavaScript LISP"]
329
+
330
+ 同じitemが何度も出てくると検索結果が見にくいので、item毎にグ
331
+ ループ化してみます。
332
+
333
+ >> records.group("item").each do |record|
334
+ >> item = record.key
335
+ >> p [record.n_sub_records,
336
+ >> item.key,
337
+ >> item[".title"]]
338
+ >> end
339
+ [1, "http://d.hatena.ne.jp/brazil/20050829/1125321936", "[翻訳]JavaScript: 世界で最も誤解されたプログラミング言語"]
340
+ [2, "http://practical-scheme.net/docs/cont-j.html", "なんでも継続"]
341
+ [1, "http://d.hatena.ne.jp/higepon/20070815/1187192864", "末尾再帰"]
342
+
343
+ +n_sub_records+というのはグループ化した単位に含まれるレコード
344
+ の件数を示します。SQLで言えば、GROUP BY句を含むクエリのcount
345
+ 関数のような働きです。
346
+
347
+ == 少し複雑な検索
348
+
349
+ ↓はまだ動かない!!!
350
+
351
+ さらに実用的な検索について考えてみましょう。
352
+
353
+ ブックマークが大量に蓄積されるに従って、より的確に適合度を算
354
+ 出する必要性に迫られます。
355
+
356
+ 今のところ検索対象として利用できるのは<tt>Items.title</tt>
357
+ と<tt>Comments.content</tt>ですが、<tt>Items.title</tt>は
358
+ 元ページから得られるやや信頼できる情報なのに対して、
359
+ <tt>Comments.content</tt>はブックマークユーザが任意に設定で
360
+ きる情報で、やや信憑性に乏しいと言えます。しかし、再現率を確
361
+ 保するためにはユーザのコメントも是非対象に含めたいところです。
362
+
363
+ そこで、以下のようなポリシーで検索を行うことにします。
364
+
365
+ * <tt>Items.title</tt>か<tt>Comments.content</tt>のいずれ
366
+ かにマッチするitemを検索する。
367
+ * ただし、<tt>Items.title</tt>にマッチしたレコードはスコア
368
+ を10倍重み付けする。
369
+ * 同一のitemに対して、キーワードにマッチする<tt>comment</tt>
370
+ が複数存在した場合は、それぞれの<tt>comment</tt>のスコアの
371
+ 和を、該当するitemのスコアとする。
372
+
373
+ 以下のようにして、commentとitemとそれぞれに対する検索結果を求
374
+ めます。
375
+
376
+ >> ruby_comments = @comments.select {|record| record["content"] =~ "Ruby"}
377
+ #<Groonga::Hash ..., size: <2>>
378
+ >> ruby_items = @items.select("*W1:50 title:@Ruby")
379
+ #<Groonga::Hash ..., size: <2>>
380
+
381
+ _ruby_comments_の結果をitem毎にグループ化し、_ruby_items_と
382
+ unionして出力します。
383
+
384
+ >> ruby_items = ruby_comments.group("item").union!(ruby_items)
385
+ #<Groonga::Hash ..., size: <4>>
386
+ >> ruby_items.sort([{:key => "._score", :order => "descendant"}]).each do |record|
387
+ >> p [record["._score"], record[".title"]]
388
+ >> end
389
+ [1, "るびま"]
390
+ [1, "オブジェクトスクリプト言語Ruby"]
391
+ [1, "Ruby"]
392
+ [1, "ラングバ"]
393
+
394
+ これで目的の結果が得られました。(FIXME: 得られていない!)