rroonga 3.0.1 → 3.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/doc/text/news.textile +21 -0
- data/ext/groonga/rb-grn-index-column.c +353 -1
- data/ext/groonga/rb-grn-object.c +529 -495
- data/ext/groonga/rb-grn-table.c +48 -0
- data/ext/groonga/rb-grn-utils.c +585 -418
- data/ext/groonga/rb-grn.h +6 -4
- data/lib/groonga/dumper.rb +25 -8
- data/lib/groonga/record.rb +21 -2
- data/lib/groonga/schema.rb +2 -2
- data/rroonga-build.rb +1 -1
- data/rroonga.gemspec +2 -0
- data/test/test-database-dumper.rb +45 -3
- data/test/test-expression-builder.rb +0 -13
- data/test/test-fix-size-column.rb +40 -9
- data/test/test-index-column.rb +130 -1
- data/test/test-record.rb +43 -8
- data/test/test-schema-create-table.rb +2 -2
- data/test/test-schema-dumper.rb +46 -6
- data/test/test-table.rb +4 -3
- data/test/test-variable-size-column.rb +115 -26
- metadata +123 -123
data/ext/groonga/rb-grn.h
CHANGED
@@ -76,7 +76,7 @@ RB_GRN_BEGIN_DECLS
|
|
76
76
|
|
77
77
|
#define RB_GRN_MAJOR_VERSION 3
|
78
78
|
#define RB_GRN_MINOR_VERSION 0
|
79
|
-
#define RB_GRN_MICRO_VERSION
|
79
|
+
#define RB_GRN_MICRO_VERSION 2
|
80
80
|
|
81
81
|
#define RB_GRN_QUERY_DEFAULT_MAX_EXPRESSIONS 32
|
82
82
|
|
@@ -616,8 +616,8 @@ VALUE rb_grn_column_expression_builder_build
|
|
616
616
|
|
617
617
|
#define RVAL2GRNUVECTOR(object, context, uvector, related_object) \
|
618
618
|
(rb_grn_uvector_from_ruby_object(object, context, uvector, related_object))
|
619
|
-
#define GRNUVECTOR2RVAL(context, uvector)
|
620
|
-
(rb_grn_uvector_to_ruby_object(context, uvector))
|
619
|
+
#define GRNUVECTOR2RVAL(context, uvector, range, related_object) \
|
620
|
+
(rb_grn_uvector_to_ruby_object(context, uvector, range, related_object))
|
621
621
|
|
622
622
|
#define GRNVALUE2RVAL(context, value, range, related_object) \
|
623
623
|
(rb_grn_value_to_ruby_object(context, value, range, related_object))
|
@@ -735,7 +735,9 @@ grn_obj *rb_grn_uvector_from_ruby_object (VALUE object,
|
|
735
735
|
grn_obj *uvector,
|
736
736
|
VALUE related_object);
|
737
737
|
VALUE rb_grn_uvector_to_ruby_object (grn_ctx *context,
|
738
|
-
grn_obj *uvector
|
738
|
+
grn_obj *uvector,
|
739
|
+
grn_obj *range,
|
740
|
+
VALUE related_object);
|
739
741
|
|
740
742
|
VALUE rb_grn_value_to_ruby_object (grn_ctx *context,
|
741
743
|
grn_obj *value,
|
data/lib/groonga/dumper.rb
CHANGED
@@ -54,15 +54,12 @@ module Groonga
|
|
54
54
|
options[:context] ||= Groonga::Context.default
|
55
55
|
options[:database] = options[:context].database
|
56
56
|
end
|
57
|
-
options[:dump_plugins] = true if options[:dump_plugins].nil?
|
58
57
|
options[:dump_schema] = true if options[:dump_schema].nil?
|
59
58
|
options[:dump_tables] = true if options[:dump_tables].nil?
|
60
59
|
|
61
60
|
if options[:dump_schema]
|
61
|
+
dump_plugins(options)
|
62
62
|
schema_dumper = SchemaDumper.new(options.merge(:syntax => :command))
|
63
|
-
end
|
64
|
-
dump_plugins(options) if options[:dump_plugins]
|
65
|
-
if options[:dump_schema]
|
66
63
|
schema_dumper.dump_tables
|
67
64
|
if schema_dumper.have_reference_columns?
|
68
65
|
options[:output].write("\n")
|
@@ -102,6 +99,7 @@ module Groonga
|
|
102
99
|
options[:database].each(each_options(:order_by => :key)) do |object|
|
103
100
|
next unless object.is_a?(Groonga::Table)
|
104
101
|
next if object.size.zero?
|
102
|
+
next if index_only_table?(object)
|
105
103
|
next if target_table?(options[:exclude_tables], object, false)
|
106
104
|
next unless target_table?(options[:tables], object, true)
|
107
105
|
options[:output].write("\n") if !first_table or options[:dump_schema]
|
@@ -124,6 +122,12 @@ module Groonga
|
|
124
122
|
output.write("register #{plugin_name}\n")
|
125
123
|
end
|
126
124
|
|
125
|
+
def index_only_table?(table)
|
126
|
+
table.columns.all? do |column|
|
127
|
+
column.index?
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
127
131
|
def target_table?(target_tables, table, default_value)
|
128
132
|
return default_value if target_tables.nil? or target_tables.empty?
|
129
133
|
target_tables.any? do |name|
|
@@ -277,8 +281,17 @@ module Groonga
|
|
277
281
|
|
278
282
|
def each_table
|
279
283
|
each_options = {:order_by => :key, :ignore_missing_object => true}
|
284
|
+
reference_tables = []
|
280
285
|
@database.each(each_options) do |object|
|
281
|
-
|
286
|
+
next unless object.is_a?(Groonga::Table)
|
287
|
+
if reference_table?(object)
|
288
|
+
reference_tables << object
|
289
|
+
else
|
290
|
+
yield(object)
|
291
|
+
end
|
292
|
+
end
|
293
|
+
reference_tables.each do |table|
|
294
|
+
yield(table)
|
282
295
|
end
|
283
296
|
end
|
284
297
|
|
@@ -287,7 +300,7 @@ module Groonga
|
|
287
300
|
sorted_columns.each(&block)
|
288
301
|
end
|
289
302
|
|
290
|
-
def
|
303
|
+
def find_all_columns
|
291
304
|
columns = []
|
292
305
|
each_table do |table|
|
293
306
|
each_column(table) do |column|
|
@@ -298,13 +311,13 @@ module Groonga
|
|
298
311
|
end
|
299
312
|
|
300
313
|
def reference_columns
|
301
|
-
@reference_columns ||=
|
314
|
+
@reference_columns ||= find_all_columns do |column|
|
302
315
|
reference_column?(column)
|
303
316
|
end
|
304
317
|
end
|
305
318
|
|
306
319
|
def index_columns
|
307
|
-
@index_columns ||=
|
320
|
+
@index_columns ||= find_all_columns do |column|
|
308
321
|
index_column?(column)
|
309
322
|
end
|
310
323
|
end
|
@@ -333,6 +346,10 @@ module Groonga
|
|
333
346
|
write("\n")
|
334
347
|
end
|
335
348
|
|
349
|
+
def reference_table?(table)
|
350
|
+
table.support_key? and table.domain.is_a?(Groonga::Table)
|
351
|
+
end
|
352
|
+
|
336
353
|
def column_type(column)
|
337
354
|
if column.is_a?(Groonga::IndexColumn)
|
338
355
|
:index
|
data/lib/groonga/record.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
2
|
#
|
3
|
-
# Copyright (C) 2009-
|
3
|
+
# Copyright (C) 2009-2013 Kouhei Sutou <kou@clear-code.com>
|
4
4
|
#
|
5
5
|
# This library is free software; you can redistribute it and/or
|
6
6
|
# modify it under the terms of the GNU Lesser General Public
|
@@ -16,6 +16,7 @@
|
|
16
16
|
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
17
17
|
|
18
18
|
require 'English'
|
19
|
+
require "time"
|
19
20
|
|
20
21
|
module Groonga
|
21
22
|
class Record
|
@@ -253,6 +254,22 @@ module Groonga
|
|
253
254
|
accessor.build
|
254
255
|
end
|
255
256
|
|
257
|
+
def as_json
|
258
|
+
accessor = AttributeHashBuilder.new(self) do |value|
|
259
|
+
if value.is_a?(Time)
|
260
|
+
value.iso8601
|
261
|
+
else
|
262
|
+
value
|
263
|
+
end
|
264
|
+
end
|
265
|
+
accessor.build
|
266
|
+
end
|
267
|
+
|
268
|
+
# @return [String] the record formatted as JSON.
|
269
|
+
def to_json(*args)
|
270
|
+
as_json.to_json(*args)
|
271
|
+
end
|
272
|
+
|
256
273
|
# レコードを削除する。
|
257
274
|
def delete
|
258
275
|
@table.delete(@id)
|
@@ -384,9 +401,10 @@ module Groonga
|
|
384
401
|
class AttributeHashBuilder
|
385
402
|
attr_reader :attributes
|
386
403
|
|
387
|
-
def initialize(root_record)
|
404
|
+
def initialize(root_record, &value_translator)
|
388
405
|
@root_record = root_record
|
389
406
|
@all_built_attributes = {}
|
407
|
+
@value_translator = value_translator
|
390
408
|
end
|
391
409
|
|
392
410
|
def build
|
@@ -415,6 +433,7 @@ module Groonga
|
|
415
433
|
if value.is_a?(Record)
|
416
434
|
build_attributes(value)
|
417
435
|
else
|
436
|
+
value = @value_translator.call(value) if @value_translator
|
418
437
|
value
|
419
438
|
end
|
420
439
|
end
|
data/lib/groonga/schema.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
2
|
#
|
3
|
-
# Copyright (C) 2009-
|
3
|
+
# Copyright (C) 2009-2013 Kouhei Sutou <kou@clear-code.com>
|
4
4
|
#
|
5
5
|
# This library is free software; you can redistribute it and/or
|
6
6
|
# modify it under the terms of the GNU Lesser General Public
|
@@ -1463,7 +1463,7 @@ module Groonga
|
|
1463
1463
|
return false unless table.range == resolve_name(options[:value_type])
|
1464
1464
|
sub_records = options[:sub_records]
|
1465
1465
|
sub_records = false if sub_records.nil?
|
1466
|
-
return false unless table.
|
1466
|
+
return false unless table.have_n_sub_records_space? == sub_records
|
1467
1467
|
|
1468
1468
|
case table
|
1469
1469
|
when Groonga::Array
|
data/rroonga-build.rb
CHANGED
data/rroonga.gemspec
CHANGED
@@ -79,6 +79,8 @@ Gem::Specification.new do |s|
|
|
79
79
|
s.require_paths = ["lib"]
|
80
80
|
s.rubyforge_project = "groonga"
|
81
81
|
|
82
|
+
s.required_ruby_version = ">= 1.9.3"
|
83
|
+
|
82
84
|
s.add_runtime_dependency("pkg-config")
|
83
85
|
s.add_runtime_dependency("json")
|
84
86
|
s.add_runtime_dependency("archive-zip")
|
@@ -107,13 +107,13 @@ column_create Users Posts_author COLUMN_INDEX Posts author
|
|
107
107
|
EOS
|
108
108
|
end
|
109
109
|
|
110
|
-
class EmptyTest <
|
110
|
+
class EmptyTest < self
|
111
111
|
def test_default
|
112
112
|
assert_equal(dumped_schema, dump)
|
113
113
|
end
|
114
114
|
end
|
115
115
|
|
116
|
-
class HaveDataTest <
|
116
|
+
class HaveDataTest < self
|
117
117
|
setup
|
118
118
|
def setup_data
|
119
119
|
posts.add(:author => "mori",
|
@@ -287,7 +287,7 @@ EOS
|
|
287
287
|
end
|
288
288
|
end
|
289
289
|
|
290
|
-
class PluginTest <
|
290
|
+
class PluginTest < self
|
291
291
|
def test_standard_plugin
|
292
292
|
Groonga::Plugin.register("suggest/suggest")
|
293
293
|
assert_equal("register suggest/suggest\n" +
|
@@ -296,4 +296,46 @@ EOS
|
|
296
296
|
dump)
|
297
297
|
end
|
298
298
|
end
|
299
|
+
|
300
|
+
class IndexTest < self
|
301
|
+
def setup_tables
|
302
|
+
Groonga::Schema.define do |schema|
|
303
|
+
schema.create_table("Posts") do |table|
|
304
|
+
table.text("title")
|
305
|
+
table.short_text("tag_text")
|
306
|
+
end
|
307
|
+
|
308
|
+
schema.create_table("Tags",
|
309
|
+
:type => :hash,
|
310
|
+
:key_type => :short_text,
|
311
|
+
:default_tokenizer => :delimit) do |table|
|
312
|
+
table.index("Posts.tag_text")
|
313
|
+
end
|
314
|
+
end
|
315
|
+
end
|
316
|
+
|
317
|
+
setup
|
318
|
+
def setup_data
|
319
|
+
posts.add(:title => "Why search engine find?",
|
320
|
+
:tag_text => "search mori")
|
321
|
+
end
|
322
|
+
|
323
|
+
def test_index_column_only
|
324
|
+
assert_equal(<<-COMMAND, dump)
|
325
|
+
table_create Posts TABLE_NO_KEY
|
326
|
+
column_create Posts tag_text COLUMN_SCALAR ShortText
|
327
|
+
column_create Posts title COLUMN_SCALAR Text
|
328
|
+
|
329
|
+
table_create Tags TABLE_HASH_KEY --key_type ShortText --default_tokenizer TokenDelimit
|
330
|
+
|
331
|
+
load --table Posts
|
332
|
+
[
|
333
|
+
["_id","tag_text","title"],
|
334
|
+
[1,"search mori","Why search engine find?"]
|
335
|
+
]
|
336
|
+
|
337
|
+
column_create Tags Posts_tag_text COLUMN_INDEX Posts tag_text
|
338
|
+
COMMAND
|
339
|
+
end
|
340
|
+
end
|
299
341
|
end
|
@@ -626,18 +626,5 @@ EOC
|
|
626
626
|
assert_equal([["morita", 2]],
|
627
627
|
result.collect {|record| [record["_key"], record.key.score]})
|
628
628
|
end
|
629
|
-
|
630
|
-
def test_n_sub_records
|
631
|
-
result = @users.select do |record|
|
632
|
-
(record.name =~ "o") | (record.key == "yu")
|
633
|
-
end
|
634
|
-
result = result.select do |record|
|
635
|
-
record.n_sub_records > 1
|
636
|
-
end
|
637
|
-
matched_records = result.collect do |record|
|
638
|
-
[record["_key"], record.key.n_sub_records]
|
639
|
-
end
|
640
|
-
assert_equal([["yu", 2]], matched_records)
|
641
|
-
end
|
642
629
|
end
|
643
630
|
end
|
@@ -64,14 +64,45 @@ class FixSizeColumnTest < Test::Unit::TestCase
|
|
64
64
|
assert_equal(@bookmarks, @viewed.table)
|
65
65
|
end
|
66
66
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
67
|
+
class TimeTest < self
|
68
|
+
class IntegerTest < self
|
69
|
+
def test_assign
|
70
|
+
comments = Groonga::Array.create(:name => "Comments")
|
71
|
+
comments.define_column("issued", "Time")
|
72
|
+
issued = 1187430026
|
73
|
+
record = comments.add(:issued => issued)
|
74
|
+
assert_equal(Time.at(issued), record["issued"])
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
class FloatTest < self
|
79
|
+
def test_assign
|
80
|
+
comments = Groonga::Array.create(:name => "Comments")
|
81
|
+
comments.define_column("issued", "Time")
|
82
|
+
issued = 1187430026.29
|
83
|
+
record = comments.add(:issued => issued)
|
84
|
+
assert_in_delta(issued, record["issued"].to_f, 0.001)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
class TimeTest < self
|
89
|
+
def test_assign
|
90
|
+
comments = Groonga::Array.create(:name => "Comments")
|
91
|
+
comments.define_column("issued", "Time")
|
92
|
+
issued_in_float = 1187430026.29
|
93
|
+
issued = Time.at(issued_in_float)
|
94
|
+
record = comments.add(:issued => issued)
|
95
|
+
assert_in_delta(issued_in_float, record["issued"].to_f, 0.001)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
class StringTest < self
|
100
|
+
def test_assign
|
101
|
+
comments = Groonga::Array.create(:name => "Comments")
|
102
|
+
comments.define_column("issued", "Time")
|
103
|
+
record = comments.add(:issued => "2010/06/01 00:00:00")
|
104
|
+
assert_equal(Time.new(2010, 6, 1, 0, 0, 0), record["issued"])
|
105
|
+
end
|
106
|
+
end
|
76
107
|
end
|
77
108
|
end
|
data/test/test-index-column.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
2
|
#
|
3
|
-
# Copyright (C) 2009-
|
3
|
+
# Copyright (C) 2009-2013 Kouhei Sutou <kou@clear-code.com>
|
4
4
|
#
|
5
5
|
# This library is free software; you can redistribute it and/or
|
6
6
|
# modify it under the terms of the GNU Lesser General Public
|
@@ -88,6 +88,135 @@ class IndexColumnTest < Test::Unit::TestCase
|
|
88
88
|
content_index.search("エンジン").collect {|record| record.key})
|
89
89
|
end
|
90
90
|
|
91
|
+
def test_add
|
92
|
+
articles = Groonga::Array.create(:name => "Articles")
|
93
|
+
articles.define_column("content", "Text")
|
94
|
+
|
95
|
+
terms = Groonga::Hash.create(:name => "Terms",
|
96
|
+
:key_type => "ShortText",
|
97
|
+
:default_tokenizer => "TokenBigram")
|
98
|
+
content_index = terms.define_index_column("content", articles,
|
99
|
+
:with_position => true,
|
100
|
+
:with_section => true)
|
101
|
+
|
102
|
+
content = <<-CONTENT
|
103
|
+
Groonga is a fast and accurate full text search engine based on
|
104
|
+
inverted index. One of the characteristics of groonga is that a
|
105
|
+
newly registered document instantly appears in search
|
106
|
+
results. Also, groonga allows updates without read locks. These
|
107
|
+
characteristics result in superior performance on real-time
|
108
|
+
applications.
|
109
|
+
|
110
|
+
Groonga is also a column-oriented database management system
|
111
|
+
(DBMS). Compared with well-known row-oriented systems, such as
|
112
|
+
MySQL and PostgreSQL, column-oriented systems are more suited for
|
113
|
+
aggregate queries. Due to this advantage, groonga can cover
|
114
|
+
weakness of row-oriented systems.
|
115
|
+
|
116
|
+
The basic functions of groonga are provided in a C library. Also,
|
117
|
+
libraries for using groonga in other languages, such as Ruby, are
|
118
|
+
provided by related projects. In addition, groonga-based storage
|
119
|
+
engines are provided for MySQL and PostgreSQL. These libraries
|
120
|
+
and storage engines allow any application to use groonga. See
|
121
|
+
usage examples.
|
122
|
+
CONTENT
|
123
|
+
|
124
|
+
groonga = articles.add(:content => content)
|
125
|
+
|
126
|
+
content.split(/\n{2,}/).each_with_index do |sentence, i|
|
127
|
+
content_index.add(groonga, sentence, :section => i + 1)
|
128
|
+
end
|
129
|
+
assert_equal([groonga], content_index.search("engine").collect(&:key))
|
130
|
+
end
|
131
|
+
|
132
|
+
def test_delete
|
133
|
+
articles = Groonga::Array.create(:name => "Articles")
|
134
|
+
articles.define_column("content", "Text")
|
135
|
+
|
136
|
+
terms = Groonga::Hash.create(:name => "Terms",
|
137
|
+
:key_type => "ShortText",
|
138
|
+
:default_tokenizer => "TokenBigram")
|
139
|
+
content_index = terms.define_index_column("content", articles,
|
140
|
+
:with_position => true,
|
141
|
+
:with_section => true)
|
142
|
+
|
143
|
+
content = <<-CONTENT
|
144
|
+
Groonga is a fast and accurate full text search engine based on
|
145
|
+
inverted index. One of the characteristics of groonga is that a
|
146
|
+
newly registered document instantly appears in search
|
147
|
+
results. Also, groonga allows updates without read locks. These
|
148
|
+
characteristics result in superior performance on real-time
|
149
|
+
applications.
|
150
|
+
|
151
|
+
Groonga is also a column-oriented database management system
|
152
|
+
(DBMS). Compared with well-known row-oriented systems, such as
|
153
|
+
MySQL and PostgreSQL, column-oriented systems are more suited for
|
154
|
+
aggregate queries. Due to this advantage, groonga can cover
|
155
|
+
weakness of row-oriented systems.
|
156
|
+
|
157
|
+
The basic functions of groonga are provided in a C library. Also,
|
158
|
+
libraries for using groonga in other languages, such as Ruby, are
|
159
|
+
provided by related projects. In addition, groonga-based storage
|
160
|
+
engines are provided for MySQL and PostgreSQL. These libraries
|
161
|
+
and storage engines allow any application to use groonga. See
|
162
|
+
usage examples.
|
163
|
+
CONTENT
|
164
|
+
|
165
|
+
groonga = articles.add(:content => content)
|
166
|
+
|
167
|
+
content.split(/\n{2,}/).each_with_index do |sentence, i|
|
168
|
+
content_index.add(groonga, sentence, :section => i + 1)
|
169
|
+
end
|
170
|
+
content.split(/\n{2,}/).each_with_index do |sentence, i|
|
171
|
+
content_index.delete(groonga, sentence, :section => i + 1)
|
172
|
+
end
|
173
|
+
assert_equal([], content_index.search("engine").collect(&:key))
|
174
|
+
end
|
175
|
+
|
176
|
+
def test_update
|
177
|
+
articles = Groonga::Array.create(:name => "Articles")
|
178
|
+
articles.define_column("content", "Text")
|
179
|
+
|
180
|
+
terms = Groonga::Hash.create(:name => "Terms",
|
181
|
+
:key_type => "ShortText",
|
182
|
+
:default_tokenizer => "TokenBigram")
|
183
|
+
content_index = terms.define_index_column("content", articles,
|
184
|
+
:with_position => true,
|
185
|
+
:with_section => true)
|
186
|
+
|
187
|
+
old_sentence = <<-SENTENCE
|
188
|
+
Groonga is a fast and accurate full text search engine based on
|
189
|
+
inverted index. One of the characteristics of groonga is that a
|
190
|
+
newly registered document instantly appears in search
|
191
|
+
results. Also, groonga allows updates without read locks. These
|
192
|
+
characteristics result in superior performance on real-time
|
193
|
+
applications.
|
194
|
+
SENTENCE
|
195
|
+
|
196
|
+
new_sentence = <<-SENTENCE
|
197
|
+
Groonga is also a column-oriented database management system
|
198
|
+
(DBMS). Compared with well-known row-oriented systems, such as
|
199
|
+
MySQL and PostgreSQL, column-oriented systems are more suited for
|
200
|
+
aggregate queries. Due to this advantage, groonga can cover
|
201
|
+
weakness of row-oriented systems.
|
202
|
+
SENTENCE
|
203
|
+
|
204
|
+
groonga = articles.add(:content => old_sentence)
|
205
|
+
|
206
|
+
content_index.add(groonga, old_sentence, :section => 1)
|
207
|
+
assert_equal([groonga],
|
208
|
+
content_index.search("engine").collect(&:key))
|
209
|
+
assert_equal([],
|
210
|
+
content_index.search("MySQL").collect(&:key))
|
211
|
+
|
212
|
+
groonga[:content] = new_sentence
|
213
|
+
content_index.update(groonga, old_sentence, new_sentence, :section => 1)
|
214
|
+
assert_equal([],
|
215
|
+
content_index.search("engine").collect(&:key))
|
216
|
+
assert_equal([groonga],
|
217
|
+
content_index.search("MySQL").collect(&:key))
|
218
|
+
end
|
219
|
+
|
91
220
|
def test_shorter_query_than_ngram
|
92
221
|
articles = Groonga::Array.create(:name => "Articles")
|
93
222
|
articles.define_column("content", "Text")
|