picky 4.3.1 → 4.3.2
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/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
|