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.
- data/NEWS.ja.rdoc +29 -0
- data/NEWS.rdoc +29 -0
- data/Rakefile +6 -6
- data/ext/groonga/rb-grn-array.c +1 -1
- data/ext/groonga/rb-grn-context.c +15 -28
- data/ext/groonga/rb-grn-exception.c +46 -1
- data/ext/groonga/rb-grn-expression.c +22 -13
- data/ext/groonga/rb-grn-fix-size-column.c +2 -8
- data/ext/groonga/rb-grn-hash.c +8 -1
- data/ext/groonga/rb-grn-object.c +1 -1
- data/ext/groonga/rb-grn-patricia-trie.c +23 -1
- data/ext/groonga/rb-grn-table-key-support.c +22 -0
- data/ext/groonga/rb-grn-table.c +37 -5
- data/ext/groonga/rb-grn-utils.c +20 -2
- data/ext/groonga/rb-grn.h +1 -1
- data/ext/groonga/rb-groonga.c +76 -38
- data/extconf.rb +17 -1
- data/html/developer.html +32 -7
- data/html/footer.html.erb +5 -0
- data/html/heading-mark.svg +393 -0
- data/html/index.html +33 -3
- data/lib/1.8/groonga.so +0 -0
- data/lib/1.9/groonga.so +0 -0
- data/lib/groonga.rb +3 -7
- data/lib/groonga/context.rb +2 -13
- data/lib/groonga/expression-builder.rb +273 -67
- data/lib/groonga/pagination.rb +143 -0
- data/lib/groonga/record.rb +2 -0
- data/lib/groonga/schema.rb +140 -29
- data/pkg/rroonga-0.9.5/NEWS.ja.rdoc +156 -0
- data/pkg/rroonga-0.9.5/NEWS.rdoc +158 -0
- data/pkg/rroonga-0.9.5/README.ja.rdoc +65 -0
- data/pkg/rroonga-0.9.5/README.rdoc +66 -0
- data/pkg/rroonga-0.9.5/text/TUTORIAL.ja.rdoc +394 -0
- data/pkg/rroonga-0.9.5/text/expression.rdoc +285 -0
- data/rroonga-build.rb +2 -2
- data/test-unit/Rakefile +40 -0
- data/test-unit/TODO +5 -0
- data/test-unit/bin/testrb +5 -0
- data/test-unit/html/classic.html +15 -0
- data/test-unit/html/index.html +25 -0
- data/test-unit/html/index.html.ja +27 -0
- data/test-unit/lib/test/unit.rb +323 -0
- data/test-unit/lib/test/unit/assertionfailederror.rb +25 -0
- data/test-unit/lib/test/unit/assertions.rb +1230 -0
- data/test-unit/lib/test/unit/attribute.rb +125 -0
- data/test-unit/lib/test/unit/autorunner.rb +360 -0
- data/test-unit/lib/test/unit/collector.rb +36 -0
- data/test-unit/lib/test/unit/collector/descendant.rb +23 -0
- data/test-unit/lib/test/unit/collector/dir.rb +108 -0
- data/test-unit/lib/test/unit/collector/load.rb +144 -0
- data/test-unit/lib/test/unit/collector/objectspace.rb +34 -0
- data/test-unit/lib/test/unit/color-scheme.rb +102 -0
- data/test-unit/lib/test/unit/color.rb +96 -0
- data/test-unit/lib/test/unit/diff.rb +724 -0
- data/test-unit/lib/test/unit/error.rb +130 -0
- data/test-unit/lib/test/unit/exceptionhandler.rb +39 -0
- data/test-unit/lib/test/unit/failure.rb +136 -0
- data/test-unit/lib/test/unit/fixture.rb +176 -0
- data/test-unit/lib/test/unit/notification.rb +129 -0
- data/test-unit/lib/test/unit/omission.rb +191 -0
- data/test-unit/lib/test/unit/pending.rb +150 -0
- data/test-unit/lib/test/unit/priority.rb +180 -0
- data/test-unit/lib/test/unit/runner/console.rb +52 -0
- data/test-unit/lib/test/unit/runner/emacs.rb +8 -0
- data/test-unit/lib/test/unit/runner/tap.rb +8 -0
- data/test-unit/lib/test/unit/testcase.rb +476 -0
- data/test-unit/lib/test/unit/testresult.rb +89 -0
- data/test-unit/lib/test/unit/testsuite.rb +110 -0
- data/test-unit/lib/test/unit/ui/console/outputlevel.rb +14 -0
- data/test-unit/lib/test/unit/ui/console/testrunner.rb +466 -0
- data/test-unit/lib/test/unit/ui/emacs/testrunner.rb +63 -0
- data/test-unit/lib/test/unit/ui/tap/testrunner.rb +92 -0
- data/test-unit/lib/test/unit/ui/testrunner.rb +28 -0
- data/test-unit/lib/test/unit/ui/testrunnermediator.rb +77 -0
- data/test-unit/lib/test/unit/ui/testrunnerutilities.rb +41 -0
- data/test-unit/lib/test/unit/util/backtracefilter.rb +41 -0
- data/test-unit/lib/test/unit/util/method-owner-finder.rb +28 -0
- data/test-unit/lib/test/unit/util/observable.rb +90 -0
- data/test-unit/lib/test/unit/util/procwrapper.rb +48 -0
- data/test-unit/lib/test/unit/version.rb +7 -0
- data/test-unit/sample/adder.rb +13 -0
- data/test-unit/sample/subtracter.rb +12 -0
- data/test-unit/sample/test_adder.rb +20 -0
- data/test-unit/sample/test_subtracter.rb +20 -0
- data/test-unit/sample/test_user.rb +23 -0
- data/test-unit/test/collector/test-descendant.rb +133 -0
- data/test-unit/test/collector/test-load.rb +442 -0
- data/test-unit/test/collector/test_dir.rb +406 -0
- data/test-unit/test/collector/test_objectspace.rb +100 -0
- data/test-unit/test/run-test.rb +15 -0
- data/test-unit/test/test-attribute.rb +86 -0
- data/test-unit/test/test-color-scheme.rb +67 -0
- data/test-unit/test/test-color.rb +47 -0
- data/test-unit/test/test-diff.rb +518 -0
- data/test-unit/test/test-emacs-runner.rb +60 -0
- data/test-unit/test/test-fixture.rb +287 -0
- data/test-unit/test/test-notification.rb +33 -0
- data/test-unit/test/test-omission.rb +81 -0
- data/test-unit/test/test-pending.rb +70 -0
- data/test-unit/test/test-priority.rb +119 -0
- data/test-unit/test/test-testcase.rb +544 -0
- data/test-unit/test/test_assertions.rb +1151 -0
- data/test-unit/test/test_error.rb +26 -0
- data/test-unit/test/test_failure.rb +33 -0
- data/test-unit/test/test_testresult.rb +113 -0
- data/test-unit/test/test_testsuite.rb +129 -0
- data/test-unit/test/testunit-test-util.rb +14 -0
- data/test-unit/test/ui/test_testrunmediator.rb +20 -0
- data/test-unit/test/util/test-method-owner-finder.rb +38 -0
- data/test-unit/test/util/test_backtracefilter.rb +41 -0
- data/test-unit/test/util/test_observable.rb +102 -0
- data/test-unit/test/util/test_procwrapper.rb +36 -0
- data/test/groonga-test-utils.rb +3 -2
- data/test/run-test.rb +14 -2
- data/test/test-column.rb +7 -7
- data/test/test-context-select.rb +34 -11
- data/test/test-exception.rb +3 -0
- data/test/test-expression-builder.rb +11 -0
- data/test/test-expression.rb +3 -6
- data/test/test-gqtp.rb +3 -5
- data/test/test-pagination.rb +249 -0
- data/test/test-record.rb +36 -8
- data/test/test-remote.rb +11 -4
- data/test/test-schema-create-table.rb +251 -0
- data/test/test-schema.rb +4 -24
- data/test/test-table-offset-and-limit.rb +3 -5
- data/test/test-table-select-mecab.rb +80 -0
- data/test/test-table-select-weight.rb +104 -0
- data/test/test-table.rb +22 -4
- data/test/test-version.rb +1 -1
- data/text/TUTORIAL.ja.rdoc +2 -0
- data/text/expression.rdoc +1 -0
- data/vendor/local/bin/grntest.exe +0 -0
- data/vendor/local/bin/groonga.exe +0 -0
- data/vendor/local/bin/libgroonga-0.dll +0 -0
- data/vendor/local/include/{groonga.h → groonga/groonga.h} +93 -32
- data/vendor/local/lib/groonga/modules/functions/cast.dll +0 -0
- data/vendor/local/lib/groonga/modules/functions/cast.la +41 -0
- data/vendor/local/lib/pkgconfig/groonga.pc +12 -0
- data/vendor/local/share/groonga/admin_html/css/admin.css +104 -0
- data/vendor/local/share/groonga/admin_html/css/ui-lightness/jquery-ui-1.8.1.custom.css +486 -0
- data/vendor/local/share/groonga/admin_html/index.html +1355 -0
- data/vendor/local/share/groonga/admin_html/js/jquery-1.4.2.min.js +154 -0
- data/vendor/local/share/groonga/admin_html/js/jquery-ui-1.8.1.custom.min.js +756 -0
- data/vendor/local/share/groonga/munin/plugins/groonga_cpu_load +47 -0
- data/vendor/local/share/groonga/munin/plugins/groonga_cpu_time +57 -0
- data/vendor/local/share/groonga/munin/plugins/groonga_disk +162 -0
- data/vendor/local/share/groonga/munin/plugins/groonga_memory +51 -0
- data/vendor/local/share/groonga/munin/plugins/groonga_n_records +110 -0
- data/vendor/local/share/groonga/munin/plugins/groonga_query_performance +133 -0
- data/vendor/local/share/groonga/munin/plugins/groonga_status +84 -0
- 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: 得られていない!)
|