picky 4.3.1 → 4.3.2
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/picky/query/token.rb +110 -8
- data/spec/functional/custom_delimiters_spec.rb +79 -0
- metadata +19 -17
data/lib/picky/query/token.rb
CHANGED
@@ -99,34 +99,107 @@ module Picky
|
|
99
99
|
# So "hello*" will not be partially searched.
|
100
100
|
# So "hello"* will be partially searched.
|
101
101
|
#
|
102
|
+
@@no_partial_character = '"'
|
103
|
+
@@partial_character = '*'
|
102
104
|
@@no_partial = /\"\z/
|
103
105
|
@@partial = /\*\z/
|
104
106
|
def partialize
|
105
107
|
self.partial = false or return unless @text !~ @@no_partial
|
106
108
|
self.partial = true unless @text !~ @@partial
|
107
109
|
end
|
110
|
+
# Define a character which stops a token from
|
111
|
+
# being a partial token, even if it is the last token.
|
112
|
+
#
|
113
|
+
# Default is '"'.
|
114
|
+
#
|
115
|
+
# This is used in a regexp (%r{#{char}\z}) for String#!~,
|
116
|
+
# so escape the character.
|
117
|
+
#
|
118
|
+
# Example:
|
119
|
+
# Picky::Query::Token.no_partial_character = '\?'
|
120
|
+
# try.search("tes?") # Won't find "test".
|
121
|
+
#
|
122
|
+
def self.no_partial_character= character
|
123
|
+
@@no_partial_character = character
|
124
|
+
@@no_partial = %r{#{character}\z}
|
125
|
+
end
|
126
|
+
# Define a character which makes a token a partial token.
|
127
|
+
#
|
128
|
+
# Default is '*'.
|
129
|
+
#
|
130
|
+
# This is used in a regexp (%r{#{char}\z}) for String#!~,
|
131
|
+
# so escape the character.
|
132
|
+
#
|
133
|
+
# Example:
|
134
|
+
# Picky::Query::Token.partial_character = '\?'
|
135
|
+
# try.search("tes?") # Will find "test".
|
136
|
+
#
|
137
|
+
def self.partial_character= character
|
138
|
+
@@partial_character = character
|
139
|
+
@@partial = %r{#{character}\z}
|
140
|
+
redefine_illegals
|
141
|
+
end
|
108
142
|
|
109
143
|
# If the text ends with ~ similarize it. If with ", don't.
|
110
144
|
#
|
111
145
|
# The latter wins.
|
112
146
|
#
|
113
|
-
@@
|
114
|
-
@@
|
147
|
+
@@no_similar_character = '"'
|
148
|
+
@@similar_character = '~'
|
149
|
+
@@no_similar = %r{#{@@no_similar_character}\z}
|
150
|
+
@@similar = %r{#{@@similar_character}\z}
|
115
151
|
def similarize
|
116
152
|
self.similar = false or return unless @text !~ @@no_similar
|
117
153
|
self.similar = true unless @text !~ @@similar
|
118
154
|
end
|
119
|
-
|
155
|
+
# Define a character which stops a token from
|
156
|
+
# being a similar token, even if it is the last token.
|
157
|
+
#
|
158
|
+
# Default is '"'.
|
159
|
+
#
|
160
|
+
# This is used in a regexp (%r{#{char}\z}) for String#!~,
|
161
|
+
# so escape the character.
|
162
|
+
#
|
163
|
+
# Example:
|
164
|
+
# Picky::Query::Token.no_similar_character = '\?'
|
165
|
+
# try.search("tost?") # Won't find "test".
|
166
|
+
#
|
167
|
+
def self.no_similar_character= character
|
168
|
+
@@no_similar_character = character
|
169
|
+
@@no_similar = %r{#{character}\z}
|
170
|
+
end
|
171
|
+
# Define a character which makes a token a similar token.
|
172
|
+
#
|
173
|
+
# Default is '~'.
|
174
|
+
#
|
175
|
+
# This is used in a regexp (%r{#{char}\z}) for String#!~,
|
176
|
+
# so escape the character.
|
177
|
+
#
|
178
|
+
# Example:
|
179
|
+
# Picky::Query::Token.similar_character = '\?'
|
180
|
+
# try.search("tost?") # Will find "test".
|
181
|
+
#
|
182
|
+
def self.similar_character= character
|
183
|
+
@@similar_character = character
|
184
|
+
@@similar = %r{#{character}\z}
|
185
|
+
redefine_illegals
|
186
|
+
end
|
187
|
+
|
188
|
+
# Is this a "similar" character?
|
189
|
+
#
|
120
190
|
def similar?
|
121
191
|
@similar
|
122
192
|
end
|
123
193
|
|
124
194
|
# Normalizes this token's text.
|
125
195
|
#
|
126
|
-
@@illegals = /["*~]/
|
127
196
|
def remove_illegals
|
128
197
|
@text.gsub! @@illegals, EMPTY_STRING unless @text.blank?
|
129
198
|
end
|
199
|
+
def self.redefine_illegals
|
200
|
+
@@illegals = %r{[#{@@no_similar_character}#{@@partial_character}#{@@similar_character}]}
|
201
|
+
end
|
202
|
+
redefine_illegals
|
130
203
|
|
131
204
|
# Returns an array of possible combinations.
|
132
205
|
#
|
@@ -145,17 +218,46 @@ module Picky
|
|
145
218
|
|
146
219
|
# Splits text into a qualifier and text.
|
147
220
|
#
|
148
|
-
@@
|
149
|
-
@@
|
221
|
+
@@qualifier_text_delimiter = ':'
|
222
|
+
@@qualifiers_delimiter = ','
|
150
223
|
def qualify
|
151
|
-
@qualifiers, @text = (@text || EMPTY_STRING).split(@@
|
224
|
+
@qualifiers, @text = (@text || EMPTY_STRING).split(@@qualifier_text_delimiter, 2)
|
152
225
|
if @text.blank?
|
153
226
|
@text = @qualifiers || EMPTY_STRING
|
154
227
|
@qualifiers = nil
|
155
228
|
else
|
156
|
-
@qualifiers = @qualifiers.split @@
|
229
|
+
@qualifiers = @qualifiers.split @@qualifiers_delimiter
|
157
230
|
end
|
158
231
|
end
|
232
|
+
# Define a character which separates the qualifier
|
233
|
+
# from the search text.
|
234
|
+
#
|
235
|
+
# Default is ':'.
|
236
|
+
#
|
237
|
+
# This is used in a String#split.
|
238
|
+
#
|
239
|
+
# Example:
|
240
|
+
# Picky::Query::Token.qualifier_text_delimiter = '?'
|
241
|
+
# try.search("text1?hello text2?world").ids.should == [1]
|
242
|
+
#
|
243
|
+
def self.qualifier_text_delimiter= character
|
244
|
+
@@qualifier_text_delimiter = character
|
245
|
+
end
|
246
|
+
# Define a character which separates the qualifiers
|
247
|
+
# (before the search text).
|
248
|
+
#
|
249
|
+
# Default is ','.
|
250
|
+
#
|
251
|
+
# This is used in a String#split.
|
252
|
+
#
|
253
|
+
# Example:
|
254
|
+
# Picky::Query::Token.qualifiers_delimiter = '|'
|
255
|
+
# try.search("text1|text2:hello").ids.should == [1]
|
256
|
+
#
|
257
|
+
|
258
|
+
def self.qualifiers_delimiter= character
|
259
|
+
@@qualifiers_delimiter = character
|
260
|
+
end
|
159
261
|
|
160
262
|
# Returns the qualifiers as an array.
|
161
263
|
#
|
@@ -0,0 +1,79 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
#
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe 'custom delimiters' do
|
6
|
+
|
7
|
+
after(:each) do
|
8
|
+
Picky::Query::Token.partial_character = '\*'
|
9
|
+
Picky::Query::Token.no_partial_character = '"'
|
10
|
+
Picky::Query::Token.similar_character = '~'
|
11
|
+
Picky::Query::Token.no_similar_character = '"'
|
12
|
+
Picky::Query::Token.qualifier_text_delimiter = ':'
|
13
|
+
Picky::Query::Token.qualifiers_delimiter = ','
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'offers custom partial delimiters to be set' do
|
17
|
+
index = Picky::Index.new :custom_delimiters do
|
18
|
+
category :text1
|
19
|
+
category :text2
|
20
|
+
end
|
21
|
+
|
22
|
+
index.add Struct.new(:id, :text1, :text2).new(1, 'hello', 'world')
|
23
|
+
|
24
|
+
try = Picky::Search.new index
|
25
|
+
try.search("hell world").ids.should == []
|
26
|
+
try.search("hell* world").ids.should == [1]
|
27
|
+
try.search("hello world").ids.should == [1]
|
28
|
+
|
29
|
+
try.search("hell! world").ids.should == []
|
30
|
+
Picky::Query::Token.partial_character = '!'
|
31
|
+
try.search("hell! world").ids.should == [1]
|
32
|
+
|
33
|
+
try.search('hell!" world').ids.should == []
|
34
|
+
Picky::Query::Token.no_partial_character = '\?'
|
35
|
+
try.search('hell!? world').ids.should == []
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'offers custom similar delimiters to be set' do
|
39
|
+
index = Picky::Index.new :custom_delimiters do
|
40
|
+
category :text1, similarity: Picky::Similarity::Soundex.new
|
41
|
+
category :text2
|
42
|
+
end
|
43
|
+
|
44
|
+
index.add Struct.new(:id, :text1, :text2).new(1, 'hello', 'world')
|
45
|
+
|
46
|
+
try = Picky::Search.new index
|
47
|
+
try.search("hell world").ids.should == []
|
48
|
+
try.search("hell~ world").ids.should == [1]
|
49
|
+
try.search("hello world").ids.should == [1]
|
50
|
+
|
51
|
+
try.search("hell? world").ids.should == []
|
52
|
+
Picky::Query::Token.similar_character = '\?'
|
53
|
+
try.search("hell? world").ids.should == [1]
|
54
|
+
|
55
|
+
try.search('hell?" world').ids.should == []
|
56
|
+
Picky::Query::Token.no_partial_character = '!'
|
57
|
+
try.search('hell?! world').ids.should == []
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'offers custom similar delimiters to be set' do
|
61
|
+
index = Picky::Index.new :custom_delimiters do
|
62
|
+
category :text1, similarity: Picky::Similarity::Soundex.new
|
63
|
+
category :text2
|
64
|
+
end
|
65
|
+
|
66
|
+
index.add Struct.new(:id, :text1, :text2).new(1, 'hello world', 'world')
|
67
|
+
|
68
|
+
try = Picky::Search.new index
|
69
|
+
try.search("text1:hello text2:world").ids.should == [1]
|
70
|
+
|
71
|
+
try.search("text1?hello text2?world").ids.should == []
|
72
|
+
Picky::Query::Token.qualifier_text_delimiter = '?'
|
73
|
+
try.search("text1?hello text2?world").ids.should == [1]
|
74
|
+
|
75
|
+
try.search("text1|text2?hello text2?world").ids.should == []
|
76
|
+
Picky::Query::Token.qualifiers_delimiter = '|'
|
77
|
+
try.search("text1|text2?hello text2?world").ids.should == [1]
|
78
|
+
end
|
79
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: picky
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.3.
|
4
|
+
version: 4.3.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-04-22 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rspec
|
16
|
-
requirement: &
|
16
|
+
requirement: &70364530556040 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,21 +21,21 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :development
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70364530556040
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: picky-client
|
27
|
-
requirement: &
|
27
|
+
requirement: &70364530555400 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ~>
|
31
31
|
- !ruby/object:Gem::Version
|
32
|
-
version: 4.3.
|
32
|
+
version: 4.3.2
|
33
33
|
type: :development
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *70364530555400
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: text
|
38
|
-
requirement: &
|
38
|
+
requirement: &70364530554580 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ! '>='
|
@@ -43,10 +43,10 @@ dependencies:
|
|
43
43
|
version: '0'
|
44
44
|
type: :runtime
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *70364530554580
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: yajl-ruby
|
49
|
-
requirement: &
|
49
|
+
requirement: &70364530553900 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
52
|
- - ! '>='
|
@@ -54,10 +54,10 @@ dependencies:
|
|
54
54
|
version: '0'
|
55
55
|
type: :runtime
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
57
|
+
version_requirements: *70364530553900
|
58
58
|
- !ruby/object:Gem::Dependency
|
59
59
|
name: activesupport
|
60
|
-
requirement: &
|
60
|
+
requirement: &70364530553380 !ruby/object:Gem::Requirement
|
61
61
|
none: false
|
62
62
|
requirements:
|
63
63
|
- - ~>
|
@@ -65,10 +65,10 @@ dependencies:
|
|
65
65
|
version: '3.0'
|
66
66
|
type: :runtime
|
67
67
|
prerelease: false
|
68
|
-
version_requirements: *
|
68
|
+
version_requirements: *70364530553380
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: procrastinate
|
71
|
-
requirement: &
|
71
|
+
requirement: &70364530552820 !ruby/object:Gem::Requirement
|
72
72
|
none: false
|
73
73
|
requirements:
|
74
74
|
- - ~>
|
@@ -76,10 +76,10 @@ dependencies:
|
|
76
76
|
version: '0.4'
|
77
77
|
type: :runtime
|
78
78
|
prerelease: false
|
79
|
-
version_requirements: *
|
79
|
+
version_requirements: *70364530552820
|
80
80
|
- !ruby/object:Gem::Dependency
|
81
81
|
name: rack_fast_escape
|
82
|
-
requirement: &
|
82
|
+
requirement: &70364530552440 !ruby/object:Gem::Requirement
|
83
83
|
none: false
|
84
84
|
requirements:
|
85
85
|
- - ! '>='
|
@@ -87,7 +87,7 @@ dependencies:
|
|
87
87
|
version: '0'
|
88
88
|
type: :runtime
|
89
89
|
prerelease: false
|
90
|
-
version_requirements: *
|
90
|
+
version_requirements: *70364530552440
|
91
91
|
description: Fast Ruby semantic text search engine with comfortable single field interface.
|
92
92
|
email: florian.hanke+picky@gmail.com
|
93
93
|
executables:
|
@@ -250,6 +250,7 @@ files:
|
|
250
250
|
- spec/functional/backends/special_spec.rb
|
251
251
|
- spec/functional/backends/sqlite_bundle_realtime_spec.rb
|
252
252
|
- spec/functional/backends/sqlite_spec.rb
|
253
|
+
- spec/functional/custom_delimiters_spec.rb
|
253
254
|
- spec/functional/dynamic_weights_spec.rb
|
254
255
|
- spec/functional/exact_first_spec.rb
|
255
256
|
- spec/functional/max_allocations_spec.rb
|
@@ -400,6 +401,7 @@ test_files:
|
|
400
401
|
- spec/functional/backends/special_spec.rb
|
401
402
|
- spec/functional/backends/sqlite_bundle_realtime_spec.rb
|
402
403
|
- spec/functional/backends/sqlite_spec.rb
|
404
|
+
- spec/functional/custom_delimiters_spec.rb
|
403
405
|
- spec/functional/dynamic_weights_spec.rb
|
404
406
|
- spec/functional/exact_first_spec.rb
|
405
407
|
- spec/functional/max_allocations_spec.rb
|