picky 3.0.1 → 3.1.0
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/application.rb +12 -12
- data/lib/picky/backends/backend.rb +17 -0
- data/lib/picky/{backend → backends}/file/basic.rb +1 -1
- data/lib/picky/{backend → backends}/file/json.rb +1 -1
- data/lib/picky/{backend → backends}/file/marshal.rb +1 -1
- data/lib/picky/{backend → backends}/file/text.rb +1 -1
- data/lib/picky/backends/memory.rb +53 -0
- data/lib/picky/{backend → backends}/redis/basic.rb +9 -14
- data/lib/picky/backends/redis/float_hash.rb +26 -0
- data/lib/picky/{backend → backends}/redis/list_hash.rb +7 -11
- data/lib/picky/{backend → backends}/redis/string_hash.rb +7 -11
- data/lib/picky/backends/redis.rb +87 -0
- data/lib/picky/bundle.rb +107 -11
- data/lib/picky/category.rb +5 -5
- data/lib/picky/index.rb +329 -0
- data/lib/picky/index_indexed.rb +31 -0
- data/lib/picky/index_indexing.rb +161 -0
- data/lib/picky/indexed/bundle.rb +112 -0
- data/lib/picky/indexed/wrappers/exact_first.rb +1 -1
- data/lib/picky/indexers/parallel.rb +2 -1
- data/lib/picky/indexers/serial.rb +2 -1
- data/lib/picky/indexes_indexing.rb +1 -1
- data/lib/picky/indexing/bundle.rb +188 -0
- data/lib/picky/indexing/wrappers/category/location.rb +1 -1
- data/lib/picky/interfaces/live_parameters.rb +8 -8
- data/lib/picky/loader.rb +24 -38
- data/lib/picky/migrations/from_30_to_31.rb +61 -0
- data/lib/picky/query/allocation.rb +10 -5
- data/lib/picky/query/combinations.rb +70 -0
- data/lib/picky/query/indexes.rb +8 -7
- data/lib/picky/query/indexes_check.rb +47 -0
- data/lib/picky/query/token.rb +16 -29
- data/lib/picky/query/tokens.rb +4 -20
- data/lib/picky/search.rb +51 -58
- data/lib/picky/tokenizer.rb +231 -0
- data/lib/picky/tokenizers/location.rb +1 -1
- data/lib/tasks/try.rake +4 -12
- data/lib/tasks/try.rb +37 -0
- data/spec/lib/application_spec.rb +5 -5
- data/spec/lib/{backend → backends}/file/basic_spec.rb +2 -2
- data/spec/lib/{backend → backends}/file/json_spec.rb +2 -2
- data/spec/lib/{backend → backends}/file/marshal_spec.rb +2 -2
- data/spec/lib/{backend → backends}/file/text_spec.rb +1 -1
- data/spec/lib/backends/memory_spec.rb +77 -0
- data/spec/lib/{backend → backends}/redis/basic_spec.rb +19 -21
- data/spec/lib/backends/redis/float_hash_spec.rb +38 -0
- data/spec/lib/backends/redis/list_hash_spec.rb +27 -0
- data/spec/lib/backends/redis/string_hash_spec.rb +38 -0
- data/spec/lib/backends/redis_spec.rb +79 -0
- data/spec/lib/categories_indexed_spec.rb +3 -3
- data/spec/lib/category_indexed_spec.rb +6 -6
- data/spec/lib/category_indexing_spec.rb +1 -1
- data/spec/lib/category_spec.rb +1 -1
- data/spec/lib/frontend_adapters/rack_spec.rb +2 -2
- data/spec/lib/{indexes/index_indexed_spec.rb → index_indexed_spec.rb} +1 -1
- data/spec/lib/{indexes/index_indexing_spec.rb → index_indexing_spec.rb} +1 -1
- data/spec/lib/{indexes/index_spec.rb → index_spec.rb} +1 -1
- data/spec/lib/indexed/{bundle/memory_spec.rb → memory_spec.rb} +18 -18
- data/spec/lib/indexed/wrappers/exact_first_spec.rb +2 -2
- data/spec/lib/indexing/{bundle/memory_partial_generation_speed_spec.rb → bundle_partial_generation_speed_spec.rb} +3 -3
- data/spec/lib/indexing/bundle_spec.rb +302 -0
- data/spec/lib/query/allocation_spec.rb +21 -11
- data/spec/lib/query/combination_spec.rb +2 -2
- data/spec/lib/query/{combinations/base_spec.rb → combinations_spec.rb} +1 -1
- data/spec/lib/query/indexes_check_spec.rb +25 -0
- data/spec/lib/query/indexes_spec.rb +5 -1
- data/spec/lib/query/token_spec.rb +18 -20
- data/spec/lib/query/tokens_spec.rb +14 -65
- data/spec/lib/search_spec.rb +36 -37
- data/spec/lib/tasks/try_spec.rb +51 -0
- data/spec/lib/{tokenizers/base_spec.rb → tokenizer_spec.rb} +15 -44
- metadata +64 -81
- data/lib/picky/backend/base.rb +0 -121
- data/lib/picky/backend/files.rb +0 -28
- data/lib/picky/backend/redis.rb +0 -44
- data/lib/picky/indexed/bundle/base.rb +0 -47
- data/lib/picky/indexed/bundle/memory.rb +0 -88
- data/lib/picky/indexed/bundle/redis.rb +0 -91
- data/lib/picky/indexes/index.rb +0 -328
- data/lib/picky/indexes/index_indexed.rb +0 -35
- data/lib/picky/indexes/index_indexing.rb +0 -165
- data/lib/picky/indexes/memory.rb +0 -20
- data/lib/picky/indexes/redis.rb +0 -20
- data/lib/picky/indexing/bundle/base.rb +0 -242
- data/lib/picky/indexing/bundle/memory.rb +0 -26
- data/lib/picky/indexing/bundle/redis.rb +0 -26
- data/lib/picky/query/combinations/base.rb +0 -74
- data/lib/picky/query/combinations/memory.rb +0 -52
- data/lib/picky/query/combinations/redis.rb +0 -90
- data/lib/picky/query.rb +0 -6
- data/lib/picky/tokenizers/base.rb +0 -231
- data/lib/picky/tokenizers/index.rb +0 -34
- data/lib/picky/tokenizers/query.rb +0 -61
- data/spec/lib/backend/files_spec.rb +0 -189
- data/spec/lib/backend/redis/list_hash_spec.rb +0 -40
- data/spec/lib/backend/redis/string_hash_spec.rb +0 -47
- data/spec/lib/backend/redis_spec.rb +0 -170
- data/spec/lib/indexed/bundle/redis_spec.rb +0 -41
- data/spec/lib/indexes/redis_spec.rb +0 -15
- data/spec/lib/indexing/bundle/base_spec.rb +0 -38
- data/spec/lib/indexing/bundle/memory_spec.rb +0 -287
- data/spec/lib/indexing/bundle/redis_spec.rb +0 -283
- data/spec/lib/query/combinations/memory_spec.rb +0 -158
- data/spec/lib/query/combinations/redis_spec.rb +0 -172
- data/spec/lib/tokenizers/index_spec.rb +0 -69
- data/spec/lib/tokenizers/query_spec.rb +0 -121
@@ -0,0 +1,188 @@
|
|
1
|
+
module Picky
|
2
|
+
|
3
|
+
module Indexing # :nodoc:all
|
4
|
+
|
5
|
+
# A Bundle is a number of indexes
|
6
|
+
# per [index, category] combination.
|
7
|
+
#
|
8
|
+
# At most, there are three indexes:
|
9
|
+
# * *core* index (always used)
|
10
|
+
# * *weights* index (always used)
|
11
|
+
# * *similarity* index (used with similarity)
|
12
|
+
#
|
13
|
+
# In Picky, indexing is separated from the index
|
14
|
+
# handling itself through a parallel structure.
|
15
|
+
#
|
16
|
+
# Both use methods provided by this base class, but
|
17
|
+
# have very different goals:
|
18
|
+
#
|
19
|
+
# * *Indexing*::*Bundle* is just concerned with creating index files
|
20
|
+
# and providing helper functions to e.g. check the indexes.
|
21
|
+
#
|
22
|
+
# * *Index*::*Bundle* is concerned with loading these index files into
|
23
|
+
# memory and looking up search data as fast as possible.
|
24
|
+
#
|
25
|
+
# This is the indexing bundle.
|
26
|
+
#
|
27
|
+
# It does all menial tasks that have nothing to do
|
28
|
+
# with the actual index running etc.
|
29
|
+
# (Find these in Indexed::Bundle)
|
30
|
+
#
|
31
|
+
class Bundle < Picky::Bundle
|
32
|
+
|
33
|
+
attr_reader :backend,
|
34
|
+
:prepared
|
35
|
+
|
36
|
+
attr_accessor :partial_strategy,
|
37
|
+
:weights_strategy
|
38
|
+
|
39
|
+
# When indexing, clear only clears the inverted index.
|
40
|
+
#
|
41
|
+
delegate :clear, :to => :inverted
|
42
|
+
|
43
|
+
def initialize name, category, backend, weights_strategy, partial_strategy, similarity_strategy, options = {}
|
44
|
+
super name, category, backend, similarity_strategy, options
|
45
|
+
|
46
|
+
@weights_strategy = weights_strategy
|
47
|
+
@partial_strategy = partial_strategy
|
48
|
+
@key_format = options[:key_format]
|
49
|
+
@prepared = Backends::File::Text.new category.prepared_index_path
|
50
|
+
|
51
|
+
@inverted = {}
|
52
|
+
@weights = {}
|
53
|
+
@similarity = {}
|
54
|
+
@configuration = {}
|
55
|
+
end
|
56
|
+
|
57
|
+
# Sets up a piece of the index for the given token.
|
58
|
+
#
|
59
|
+
def initialize_inverted_index_for token
|
60
|
+
self.inverted[token] ||= []
|
61
|
+
end
|
62
|
+
|
63
|
+
# Generation
|
64
|
+
#
|
65
|
+
|
66
|
+
# This method
|
67
|
+
# * Loads the base index from the "prepared..." file.
|
68
|
+
# * Generates derived indexes.
|
69
|
+
# * Dumps all the indexes into files.
|
70
|
+
#
|
71
|
+
def generate_caches_from_source
|
72
|
+
load_from_prepared_index_file
|
73
|
+
generate_caches_from_memory
|
74
|
+
end
|
75
|
+
# Generates derived indexes from the index and dumps.
|
76
|
+
#
|
77
|
+
# Note: assumes that there is something in the index
|
78
|
+
#
|
79
|
+
def generate_caches_from_memory
|
80
|
+
cache_from_memory_generation_message
|
81
|
+
generate_derived
|
82
|
+
end
|
83
|
+
def cache_from_memory_generation_message
|
84
|
+
timed_exclaim %Q{"#{identifier}": Caching from intermediate in-memory index.}
|
85
|
+
end
|
86
|
+
|
87
|
+
# Generates the weights and similarity from the main index.
|
88
|
+
#
|
89
|
+
def generate_derived
|
90
|
+
generate_weights
|
91
|
+
generate_similarity
|
92
|
+
end
|
93
|
+
|
94
|
+
# Load the data from the db.
|
95
|
+
#
|
96
|
+
def load_from_prepared_index_file
|
97
|
+
load_from_prepared_index_generation_message
|
98
|
+
clear
|
99
|
+
retrieve
|
100
|
+
end
|
101
|
+
def load_from_prepared_index_generation_message
|
102
|
+
timed_exclaim %Q{"#{identifier}": Loading prepared data into memory.}
|
103
|
+
end
|
104
|
+
# Retrieves the prepared index data into the index.
|
105
|
+
#
|
106
|
+
# This is in preparation for generating
|
107
|
+
# derived indexes (like weights, similarity)
|
108
|
+
# and later dumping the optimized index.
|
109
|
+
#
|
110
|
+
# TODO Move this out to the category?
|
111
|
+
#
|
112
|
+
def retrieve
|
113
|
+
format = category.key_format || :to_i # Optimization.
|
114
|
+
prepared.retrieve do |id, token|
|
115
|
+
initialize_inverted_index_for token
|
116
|
+
self.inverted[token] << id.send(format)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
# Generates a new index (writes its index) using the
|
121
|
+
# partial caching strategy of this bundle.
|
122
|
+
#
|
123
|
+
def generate_partial
|
124
|
+
generator = Generators::PartialGenerator.new self.inverted
|
125
|
+
self.inverted = generator.generate self.partial_strategy
|
126
|
+
end
|
127
|
+
# Generate a partial index from the given exact inverted index.
|
128
|
+
#
|
129
|
+
def generate_partial_from exact_inverted_index
|
130
|
+
timed_exclaim %Q{"#{identifier}": Generating partial index for index.}
|
131
|
+
self.inverted = exact_inverted_index
|
132
|
+
self.generate_partial
|
133
|
+
self
|
134
|
+
end
|
135
|
+
# Generates a new weights index (writes its index) using the
|
136
|
+
# given weight caching strategy.
|
137
|
+
#
|
138
|
+
def generate_weights
|
139
|
+
generator = Generators::WeightsGenerator.new self.inverted
|
140
|
+
self.weights = generator.generate self.weights_strategy
|
141
|
+
end
|
142
|
+
# Generates a new similarity index (writes its index) using the
|
143
|
+
# given similarity caching strategy.
|
144
|
+
#
|
145
|
+
def generate_similarity
|
146
|
+
generator = Generators::SimilarityGenerator.new self.inverted
|
147
|
+
self.similarity = generator.generate self.similarity_strategy
|
148
|
+
end
|
149
|
+
|
150
|
+
# Saves the indexes in a dump file.
|
151
|
+
#
|
152
|
+
def dump
|
153
|
+
timed_exclaim %Q{"#{identifier}": Dumping data.}
|
154
|
+
dump_inverted
|
155
|
+
dump_similarity
|
156
|
+
dump_weights
|
157
|
+
dump_configuration
|
158
|
+
end
|
159
|
+
# Dumps the core index.
|
160
|
+
#
|
161
|
+
def dump_inverted
|
162
|
+
# timed_exclaim %Q{"#{identifier}": Dumping inverted index.}
|
163
|
+
@backend_inverted.dump self.inverted
|
164
|
+
end
|
165
|
+
# Dumps the weights index.
|
166
|
+
#
|
167
|
+
def dump_weights
|
168
|
+
# timed_exclaim %Q{"#{identifier}": Dumping index weights.}
|
169
|
+
@backend_weights.dump self.weights
|
170
|
+
end
|
171
|
+
# Dumps the similarity index.
|
172
|
+
#
|
173
|
+
def dump_similarity
|
174
|
+
# timed_exclaim %Q{"#{identifier}": Dumping similarity index.}
|
175
|
+
@backend_similarity.dump self.similarity
|
176
|
+
end
|
177
|
+
# Dumps the similarity index.
|
178
|
+
#
|
179
|
+
def dump_configuration
|
180
|
+
# timed_exclaim %Q{"#{identifier}": Dumping configuration.}
|
181
|
+
@backend_configuration.dump self.configuration
|
182
|
+
end
|
183
|
+
|
184
|
+
end
|
185
|
+
|
186
|
+
end
|
187
|
+
|
188
|
+
end
|
@@ -144,29 +144,29 @@ module Picky
|
|
144
144
|
# TODO Move to Interface object.
|
145
145
|
#
|
146
146
|
def querying_removes_characters
|
147
|
-
regexp =
|
147
|
+
regexp = Tokenizer.query_default.instance_variable_get :@removes_characters_regexp
|
148
148
|
regexp && regexp.source
|
149
149
|
end
|
150
150
|
def querying_removes_characters= new_value
|
151
|
-
|
151
|
+
Tokenizer.query_default.instance_variable_set(:@removes_characters_regexp, %r{#{new_value}})
|
152
152
|
end
|
153
153
|
def querying_stopwords
|
154
|
-
regexp =
|
154
|
+
regexp = Tokenizer.query_default.instance_variable_get :@remove_stopwords_regexp
|
155
155
|
regexp && regexp.source
|
156
156
|
end
|
157
157
|
def querying_stopwords= new_value
|
158
|
-
|
158
|
+
Tokenizer.query_default.instance_variable_set(:@remove_stopwords_regexp, %r{#{new_value}})
|
159
159
|
end
|
160
160
|
def querying_splits_text_on
|
161
|
-
splits =
|
161
|
+
splits = Tokenizer.query_default.instance_variable_get :@splits_text_on
|
162
162
|
splits && splits.respond_to?(:source) ? splits.source : splits
|
163
163
|
end
|
164
164
|
def querying_splits_text_on= new_value
|
165
|
-
splits =
|
165
|
+
splits = Tokenizer.query_default.instance_variable_get :@splits_text_on
|
166
166
|
if splits.respond_to?(:source)
|
167
|
-
|
167
|
+
Tokenizer.query_default.instance_variable_set(:@splits_text_on, %r{#{new_value}})
|
168
168
|
else
|
169
|
-
|
169
|
+
Tokenizer.query_default.instance_variable_set(:@splits_text_on, new_value)
|
170
170
|
end
|
171
171
|
end
|
172
172
|
|
data/lib/picky/loader.rb
CHANGED
@@ -110,34 +110,28 @@ module Picky
|
|
110
110
|
|
111
111
|
# Index store handling.
|
112
112
|
#
|
113
|
-
load_relative 'backend
|
113
|
+
load_relative 'backends/backend'
|
114
114
|
|
115
|
-
load_relative '
|
116
|
-
load_relative '
|
117
|
-
load_relative '
|
118
|
-
load_relative '
|
115
|
+
load_relative 'backends/redis'
|
116
|
+
load_relative 'backends/redis/basic'
|
117
|
+
load_relative 'backends/redis/list_hash'
|
118
|
+
load_relative 'backends/redis/string_hash'
|
119
|
+
load_relative 'backends/redis/float_hash'
|
119
120
|
|
120
|
-
load_relative '
|
121
|
-
load_relative '
|
122
|
-
load_relative '
|
123
|
-
load_relative '
|
124
|
-
|
125
|
-
load_relative 'backend/files'
|
121
|
+
load_relative 'backends/file/basic'
|
122
|
+
load_relative 'backends/file/text'
|
123
|
+
load_relative 'backends/file/marshal'
|
124
|
+
load_relative 'backends/file/json'
|
125
|
+
load_relative 'backends/memory'
|
126
126
|
|
127
127
|
# Indexing and Indexed things.
|
128
128
|
#
|
129
129
|
load_relative 'bundle'
|
130
130
|
|
131
|
-
load_relative 'indexing/bundle
|
132
|
-
load_relative 'indexing/bundle/memory'
|
133
|
-
load_relative 'indexing/bundle/redis'
|
134
|
-
|
131
|
+
load_relative 'indexing/bundle'
|
135
132
|
load_relative 'indexing/wrappers/category/location'
|
136
133
|
|
137
|
-
load_relative 'indexed/bundle
|
138
|
-
load_relative 'indexed/bundle/memory'
|
139
|
-
load_relative 'indexed/bundle/redis'
|
140
|
-
|
134
|
+
load_relative 'indexed/bundle'
|
141
135
|
load_relative 'indexed/wrappers/exact_first'
|
142
136
|
|
143
137
|
# Bundle Wrapper
|
@@ -153,18 +147,14 @@ module Picky
|
|
153
147
|
load_relative 'query/token'
|
154
148
|
load_relative 'query/tokens'
|
155
149
|
|
156
|
-
#
|
150
|
+
# Tokenizer.
|
157
151
|
#
|
158
|
-
load_relative '
|
159
|
-
load_relative 'tokenizers/index'
|
160
|
-
load_relative 'tokenizers/query'
|
152
|
+
load_relative 'tokenizer'
|
161
153
|
|
162
154
|
# Query combinations, qualifiers, weigher.
|
163
155
|
#
|
164
156
|
load_relative 'query/combination'
|
165
|
-
load_relative 'query/combinations
|
166
|
-
load_relative 'query/combinations/memory'
|
167
|
-
load_relative 'query/combinations/redis'
|
157
|
+
load_relative 'query/combinations'
|
168
158
|
|
169
159
|
load_relative 'query/allocation'
|
170
160
|
load_relative 'query/allocations'
|
@@ -174,10 +164,7 @@ module Picky
|
|
174
164
|
load_relative 'query/weights'
|
175
165
|
|
176
166
|
load_relative 'query/indexes'
|
177
|
-
|
178
|
-
# Configuration.
|
179
|
-
#
|
180
|
-
# load_internals 'configuration/index'
|
167
|
+
load_relative 'query/indexes_check'
|
181
168
|
|
182
169
|
# Adapters.
|
183
170
|
#
|
@@ -227,11 +214,9 @@ module Picky
|
|
227
214
|
load_relative 'indexes_indexed'
|
228
215
|
load_relative 'indexes_indexing'
|
229
216
|
|
230
|
-
load_relative '
|
231
|
-
load_relative '
|
232
|
-
load_relative '
|
233
|
-
load_relative 'indexes/memory'
|
234
|
-
load_relative 'indexes/redis'
|
217
|
+
load_relative 'index'
|
218
|
+
load_relative 'index_indexed'
|
219
|
+
load_relative 'index_indexing'
|
235
220
|
|
236
221
|
# Results.
|
237
222
|
#
|
@@ -240,9 +225,6 @@ module Picky
|
|
240
225
|
# Search.
|
241
226
|
#
|
242
227
|
load_relative 'search'
|
243
|
-
load_relative 'query'
|
244
|
-
#
|
245
|
-
# load_relative 'query/solr'
|
246
228
|
|
247
229
|
# Sources.
|
248
230
|
#
|
@@ -267,6 +249,10 @@ module Picky
|
|
267
249
|
# Load tools. Load in specific case?
|
268
250
|
#
|
269
251
|
load_relative 'cores'
|
252
|
+
|
253
|
+
# Load migration notices.
|
254
|
+
#
|
255
|
+
load_relative 'migrations/from_30_to_31'
|
270
256
|
end
|
271
257
|
|
272
258
|
# Loads the framework.
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module Picky
|
2
|
+
|
3
|
+
class Indexes
|
4
|
+
|
5
|
+
class Memory
|
6
|
+
|
7
|
+
def initialize(*)
|
8
|
+
raise <<-MESSAGE
|
9
|
+
|
10
|
+
The Picky::Indexes::Memory is not available anymore and has been replaced by Picky::Index.
|
11
|
+
|
12
|
+
So instead of
|
13
|
+
|
14
|
+
index = Picky::Indexes::Memory.new :name do
|
15
|
+
# your config
|
16
|
+
end
|
17
|
+
|
18
|
+
use
|
19
|
+
|
20
|
+
index = Picky::Index.new :name do
|
21
|
+
# your config
|
22
|
+
end
|
23
|
+
|
24
|
+
Thanks and sorry for the inconvenience!
|
25
|
+
|
26
|
+
MESSAGE
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
class Redis
|
32
|
+
|
33
|
+
def initialize(*)
|
34
|
+
raise <<-RAISE
|
35
|
+
|
36
|
+
The Picky::Indexes::Redis is not available anymore and has been replaced by Picky::Index.
|
37
|
+
(with the addition of a "backend" option)
|
38
|
+
|
39
|
+
So instead of
|
40
|
+
|
41
|
+
index = Picky::Indexes::Redis.new :name do
|
42
|
+
# your config
|
43
|
+
end
|
44
|
+
|
45
|
+
use
|
46
|
+
|
47
|
+
index = Picky::Index.new :name do
|
48
|
+
backend Picky::Backends::Redis.new
|
49
|
+
# your config
|
50
|
+
end
|
51
|
+
|
52
|
+
Thanks and sorry for the inconvenience!
|
53
|
+
|
54
|
+
RAISE
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
@@ -7,13 +7,18 @@ module Picky
|
|
7
7
|
#
|
8
8
|
class Allocation # :nodoc:all
|
9
9
|
|
10
|
-
attr_reader :count,
|
10
|
+
attr_reader :count,
|
11
|
+
:ids,
|
12
|
+
:score,
|
13
|
+
:combinations,
|
14
|
+
:result_identifier
|
11
15
|
|
12
16
|
#
|
13
17
|
#
|
14
|
-
def initialize
|
18
|
+
def initialize index, combinations
|
15
19
|
@combinations = combinations
|
16
|
-
@result_identifier = result_identifier
|
20
|
+
@result_identifier = index.result_identifier # TODO Make cleverer.
|
21
|
+
@backend = index.backend # TODO Make cleverer.
|
17
22
|
end
|
18
23
|
|
19
24
|
def hash
|
@@ -30,10 +35,10 @@ module Picky
|
|
30
35
|
@score ||= @combinations.calculate_score(weights)
|
31
36
|
end
|
32
37
|
|
33
|
-
# Asks the
|
38
|
+
# Asks the backend for the (intersected) ids.
|
34
39
|
#
|
35
40
|
def calculate_ids amount, offset
|
36
|
-
@
|
41
|
+
@backend.ids combinations, amount, offset
|
37
42
|
end
|
38
43
|
|
39
44
|
# This starts the searching process.
|
@@ -0,0 +1,70 @@
|
|
1
|
+
module Picky
|
2
|
+
|
3
|
+
module Query
|
4
|
+
|
5
|
+
# Combinations are a number of Combination-s.
|
6
|
+
#
|
7
|
+
# They are the core of an allocation.
|
8
|
+
# An allocation consists of a number of combinations.
|
9
|
+
#
|
10
|
+
# Base Combinations contain methods for calculating score and ids.
|
11
|
+
#
|
12
|
+
class Combinations # :nodoc:all
|
13
|
+
|
14
|
+
attr_reader :combinations
|
15
|
+
|
16
|
+
delegate :empty?, :inject, :to => :@combinations
|
17
|
+
|
18
|
+
def initialize combinations = []
|
19
|
+
@combinations = combinations
|
20
|
+
end
|
21
|
+
|
22
|
+
def hash
|
23
|
+
@combinations.hash
|
24
|
+
end
|
25
|
+
|
26
|
+
# Uses user specific weights to calculate a score for the combinations.
|
27
|
+
#
|
28
|
+
def calculate_score weights
|
29
|
+
total_score + weighted_score(weights)
|
30
|
+
end
|
31
|
+
def total_score
|
32
|
+
@combinations.sum &:weight
|
33
|
+
end
|
34
|
+
def weighted_score weights
|
35
|
+
weights.score_for @combinations
|
36
|
+
end
|
37
|
+
|
38
|
+
# Filters the tokens and identifiers such that only identifiers
|
39
|
+
# that are passed in, remain, including their tokens.
|
40
|
+
#
|
41
|
+
# Note: This method is not totally independent of the calculate_ids one.
|
42
|
+
# Since identifiers are only nullified, we need to not include the
|
43
|
+
# ids that have an associated identifier that is nil.
|
44
|
+
#
|
45
|
+
def keep identifiers = []
|
46
|
+
@combinations.reject! { |combination| !combination.in?(identifiers) }
|
47
|
+
end
|
48
|
+
|
49
|
+
# Filters the tokens and identifiers such that identifiers
|
50
|
+
# that are passed in, are removed, including their tokens.
|
51
|
+
#
|
52
|
+
# Note: This method is not totally independent of the calculate_ids one.
|
53
|
+
# Since identifiers are only nullified, we need to not include the
|
54
|
+
# ids that have an associated identifier that is nil.
|
55
|
+
#
|
56
|
+
def remove identifiers = []
|
57
|
+
@combinations.reject! { |combination| combination.in?(identifiers) }
|
58
|
+
end
|
59
|
+
|
60
|
+
#
|
61
|
+
#
|
62
|
+
def to_result
|
63
|
+
@combinations.map &:to_result
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
data/lib/picky/query/indexes.rb
CHANGED
@@ -20,10 +20,11 @@ module Picky
|
|
20
20
|
# Its job is to generate all possible combinations.
|
21
21
|
# Note: We cannot mix memory and redis indexes just yet.
|
22
22
|
#
|
23
|
-
def initialize *indexes
|
24
|
-
|
25
|
-
|
26
|
-
@
|
23
|
+
def initialize *indexes
|
24
|
+
IndexesCheck.check_backend_types indexes
|
25
|
+
|
26
|
+
@indexes = indexes
|
27
|
+
@mapper = Query::QualifierCategoryMapper.new
|
27
28
|
map_categories
|
28
29
|
end
|
29
30
|
def map_categories
|
@@ -81,12 +82,12 @@ module Picky
|
|
81
82
|
|
82
83
|
# Generate all possible combinations.
|
83
84
|
#
|
84
|
-
|
85
|
+
all_possible_combinations = expand_combinations_from possible_combinations
|
85
86
|
|
86
87
|
# Add the wrapped possible allocations to the ones we already have.
|
87
88
|
#
|
88
|
-
|
89
|
-
Allocation.new
|
89
|
+
all_possible_combinations.map! do |expanded_combinations|
|
90
|
+
Allocation.new index, Query::Combinations.new(expanded_combinations)
|
90
91
|
end
|
91
92
|
end
|
92
93
|
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module Picky
|
2
|
+
|
3
|
+
module Query
|
4
|
+
|
5
|
+
# TODO Remove.
|
6
|
+
#
|
7
|
+
class IndexesCheck
|
8
|
+
|
9
|
+
class << self
|
10
|
+
|
11
|
+
# Returns the right combinations strategy for
|
12
|
+
# a number of query indexes.
|
13
|
+
#
|
14
|
+
# Currently it isn't possible using Memory and Redis etc.
|
15
|
+
# indexes in the same query index group.
|
16
|
+
#
|
17
|
+
# Picky will raise a Query::Indexes::DifferentTypesError.
|
18
|
+
#
|
19
|
+
def check_backend_types index_definitions_ary # :nodoc:
|
20
|
+
backend_types = index_definitions_ary.map(&:backend).map(&:class)
|
21
|
+
backend_types.uniq!
|
22
|
+
raise_different backend_types if backend_types.size > 1
|
23
|
+
backend_types
|
24
|
+
end
|
25
|
+
def raise_different backend_types # :nodoc:
|
26
|
+
raise DifferentTypesError.new(backend_types)
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
# Currently it isn't possible using Memory and Redis etc.
|
34
|
+
# indexes in the same query index group.
|
35
|
+
#
|
36
|
+
class DifferentTypesError < StandardError # :nodoc:all
|
37
|
+
def initialize types
|
38
|
+
@types = types
|
39
|
+
end
|
40
|
+
def to_s
|
41
|
+
"Currently it isn't possible to mix Indexes with backends #{@types.join(" and ")} in the same Search instance."
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
data/lib/picky/query/token.rb
CHANGED
@@ -19,8 +19,9 @@ module Picky
|
|
19
19
|
#
|
20
20
|
# Note: Use this if you do not want a normalized token.
|
21
21
|
#
|
22
|
-
def initialize text
|
23
|
-
@text
|
22
|
+
def initialize text, original = nil
|
23
|
+
@text = text
|
24
|
+
@original = original
|
24
25
|
end
|
25
26
|
|
26
27
|
# Returns a qualified and normalized token.
|
@@ -28,20 +29,24 @@ module Picky
|
|
28
29
|
# Note: Use this in the search engine if you need a qualified
|
29
30
|
# and normalized token. I.e. one prepared for a search.
|
30
31
|
#
|
31
|
-
def self.processed text,
|
32
|
-
new(text).process
|
32
|
+
def self.processed text, original = nil
|
33
|
+
new(text, original).process
|
33
34
|
end
|
34
|
-
def process
|
35
|
-
qualify
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
similarize
|
40
|
-
remove_illegals
|
35
|
+
def process # TODO Move this into the processed method and let the token have more params?
|
36
|
+
qualify # TODO Should this operate on the original?
|
37
|
+
partialize # TODO Should this operate on the original?
|
38
|
+
similarize # TODO Should this operate on the original?
|
39
|
+
remove_illegals # TODO Remove?
|
41
40
|
symbolize
|
42
41
|
self
|
43
42
|
end
|
44
43
|
|
44
|
+
#
|
45
|
+
#
|
46
|
+
def symbolize
|
47
|
+
@text = @text.to_sym
|
48
|
+
end
|
49
|
+
|
45
50
|
# Translates this token's qualifiers into actual categories.
|
46
51
|
#
|
47
52
|
# Note: If this is not done, there is no mapping.
|
@@ -52,18 +57,6 @@ module Picky
|
|
52
57
|
end.compact
|
53
58
|
end
|
54
59
|
|
55
|
-
# Dups the original text.
|
56
|
-
#
|
57
|
-
def extract_original
|
58
|
-
@original = @text.dup
|
59
|
-
end
|
60
|
-
|
61
|
-
# Downcases the text.
|
62
|
-
#
|
63
|
-
def downcase
|
64
|
-
@text.downcase!
|
65
|
-
end
|
66
|
-
|
67
60
|
# Partial is a conditional setter.
|
68
61
|
#
|
69
62
|
# It is only settable if it hasn't been set yet.
|
@@ -108,12 +101,6 @@ module Picky
|
|
108
101
|
@text.gsub! @@illegals, '' unless @text.blank?
|
109
102
|
end
|
110
103
|
|
111
|
-
#
|
112
|
-
#
|
113
|
-
def symbolize
|
114
|
-
@text = @text.to_sym
|
115
|
-
end
|
116
|
-
|
117
104
|
# Returns an array of possible combinations.
|
118
105
|
#
|
119
106
|
def possible_combinations_in index
|