Class: Picky::Query::Indexes
- Defined in:
- lib/picky/query/indexes.rb,
lib/picky/query/indexes/check.rb
Overview
Defined Under Namespace
Classes: Check, DifferentBackendsError
Instance Attribute Summary collapse
-
#exclusive_allocations ⇒ Object
readonly
Returns the value of attribute exclusive_allocations.
-
#ignored_allocations ⇒ Object
readonly
Returns the value of attribute ignored_allocations.
-
#ignored_categories ⇒ Object
readonly
Returns the value of attribute ignored_categories.
-
#indexes ⇒ Object
readonly
Returns the value of attribute indexes.
Instance Method Summary collapse
- #allocation_for(tokens, index) ⇒ Object
- #allocations_ary_for(tokens) ⇒ Object
-
#allocations_for(tokens) ⇒ Object
Returns a number of possible allocations for the given tokens.
-
#expand_combinations_from(possible_combinations) ⇒ Object
This is the core of the search engine.
-
#ignore_allocations(*qualifier_arrays) ⇒ Object
Ignore the allocations with the given qualifiers.
-
#ignore_categories(*qualifiers) ⇒ Object
Ignore the categories with the given qualifiers.
-
#initialize(*indexes) ⇒ Indexes
constructor
Creates a new Query::Indexes.
-
#keep_allocations(*qualifier_arrays) ⇒ Object
Exclusively keep the allocations with the given qualifiers.
-
#prepared_allocations_for(tokens, boosts = {}, amount = nil) ⇒ Object
Returns a number of prepared (sorted, reduced etc.) allocations for the given tokens.
Constructor Details
#initialize(*indexes) ⇒ Indexes
Creates a new Query::Indexes.
Its job is to generate all possible combinations. Note: We cannot mix memory and redis indexes just yet.
28 29 30 31 32 |
# File 'lib/picky/query/indexes.rb', line 28 def initialize *indexes Check.check_backends indexes @indexes = indexes end |
Instance Attribute Details
#exclusive_allocations ⇒ Object (readonly)
Returns the value of attribute exclusive_allocations.
18 19 20 |
# File 'lib/picky/query/indexes.rb', line 18 def exclusive_allocations @exclusive_allocations end |
#ignored_allocations ⇒ Object (readonly)
Returns the value of attribute ignored_allocations.
18 19 20 |
# File 'lib/picky/query/indexes.rb', line 18 def ignored_allocations @ignored_allocations end |
#ignored_categories ⇒ Object (readonly)
Returns the value of attribute ignored_categories.
18 19 20 |
# File 'lib/picky/query/indexes.rb', line 18 def ignored_categories @ignored_categories end |
#indexes ⇒ Object (readonly)
Returns the value of attribute indexes.
18 19 20 |
# File 'lib/picky/query/indexes.rb', line 18 def indexes @indexes end |
Instance Method Details
#allocation_for(tokens, index) ⇒ Object
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 |
# File 'lib/picky/query/indexes.rb', line 110 def allocation_for tokens, index # Expand the combinations. # possible_combinations = tokens.possible_combinations_in index.categories # Generate all possible combinations. # all_possible_combinations = possible_combinations # Add the wrapped possible allocations to the ones we already have. # all_possible_combinations.map! do || Allocation.new index, Query::Combinations.new() end end |
#allocations_ary_for(tokens) ⇒ Object
105 106 107 108 109 |
# File 'lib/picky/query/indexes.rb', line 105 def allocations_ary_for tokens indexes.inject([]) do |allocations, index| allocations + allocation_for(tokens, index) end end |
#allocations_for(tokens) ⇒ Object
Returns a number of possible allocations for the given tokens.
102 103 104 |
# File 'lib/picky/query/indexes.rb', line 102 def allocations_for tokens Allocations.new allocations_ary_for(tokens) end |
#expand_combinations_from(possible_combinations) ⇒ Object
This is the core of the search engine. No kidding.
Gets an array of [
[<combinations for token1>],
[<combinations for token2>],
[<combinations for token3>]
]
Generates all possible allocations of combinations. [
[first combination of token1, first c of t2, first c of t3],
[first combination of token1, first c of t2, second c of t3]
...
]
Generates all possible combinations of array elements:
- 1,2,3
-
x [a,b,c] x [k,l,m] => [[1,a,k], [1,a,l], [1,a,m], [1,b,k], [1,b,l], [1,b,m], [1,c,k], …, [3,c,m]]
Note: Also calculates the weights and sorts them accordingly.
Note: This is a heavily optimized ruby version.
Works like this:
- 1,2,3], [a,b,c], [k,l,m
-
are expanded to
group mult: 1
<- single mult ->
- 1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3
-
27 elements
group mult: 3
<- -> s/m
- a,a,a,b,b,b,c,c,c,a,a,a,b,b,b,c,c,c,a,a,a,b,b,b,c,c,c
-
27 elements
group mult: 9
<> s/m
- k,l,m,k,l,m,k,l,m,k,l,m,k,l,m,k,l,m,k,l,m,k,l,m,k,l,m
-
27 elements
It is then recombined, where [
[a,a,b,b,c,c]
[d,e,d,e,d,e]
] becomes [
[a,d],
[a,e],
[b,d],
[b,e],
[c,d],
[c,e]
]
Note: Not using transpose as it is slower.
Returns nil if there are no combinations.
Note: Of course I could split this method up into smaller
ones, but I guess I am a bit sentimental.
182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 |
# File 'lib/picky/query/indexes.rb', line 182 def possible_combinations # If an element has size 0, this means one of the # tokens could not be allocated. # return [] if possible_combinations.any? { |possible_combination| possible_combination.empty? } # Generate the first multiplicator "with which" (well, not quite) to multiply the smallest amount of combinations. # single_mult = possible_combinations.inject(1) { |total, combinations| total * combinations.size } # Initialize a group multiplicator. # group_mult = 1 # The expanding part to line up the combinations # for later combination in allocations. # possible_combinations.collect! do |combinations| # Get the size of the combinations of the first token. # combinations_size = combinations.size # Special case: If there is no combination for one of the tokens. # In that case, we just use the same single mult for # the next iteration. # If there are combinations, we divide the single mult # by the number of combinations. # single_mult /= combinations_size unless combinations_size.zero? # Expand each combination by the single mult: # [a,b,c] # [a,a,a, b,b,b, c,c,c] # Then, expand the result by the group mult: # [a,a,a,b,b,b,c,c,c, a,a,a,b,b,b,c,c,c, a,a,a,b,b,b,c,c,c] # combinations = combinations.inject([]) do |total, combination| total + Array.new(single_mult, combination) end * group_mult # Multiply the group mult by the combinations size, # since the next combinations' single mult is smaller # and we need to adjust for that. # group_mult = group_mult * combinations_size # Return the combinations. # combinations end return [] if possible_combinations.empty? possible_combinations.shift.zip *possible_combinations end |
#ignore_allocations(*qualifier_arrays) ⇒ Object
Ignore the allocations with the given qualifiers.
45 46 47 48 49 50 51 |
# File 'lib/picky/query/indexes.rb', line 45 def ignore_allocations *qualifier_arrays @ignored_allocations ||= [] @ignored_allocations += qualifier_arrays #.map do |qualifier_array| # qualifier_array.map { |qualifier| @qualifier_mapper.map qualifier } # end.compact @ignored_allocations.uniq! end |
#ignore_categories(*qualifiers) ⇒ Object
Ignore the categories with the given qualifiers.
36 37 38 39 40 41 |
# File 'lib/picky/query/indexes.rb', line 36 def ignore_categories *qualifiers @ignored_categories ||= [] # @ignored_categories += qualifiers.map { |qualifier| @qualifier_mapper.map qualifier }.compact @ignored_categories += qualifiers @ignored_categories.uniq! end |
#keep_allocations(*qualifier_arrays) ⇒ Object
Exclusively keep the allocations with the given qualifiers.
55 56 57 58 59 60 61 |
# File 'lib/picky/query/indexes.rb', line 55 def keep_allocations *qualifier_arrays @exclusive_allocations ||= [] @exclusive_allocations += qualifier_arrays #.map do |qualifier_array| # qualifier_array.map { |qualifier| @qualifier_mapper.map qualifier } # end.compact @exclusive_allocations.uniq! end |
#prepared_allocations_for(tokens, boosts = {}, amount = nil) ⇒ Object
Returns a number of prepared (sorted, reduced etc.) allocations for the given tokens.
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
# File 'lib/picky/query/indexes.rb', line 65 def prepared_allocations_for tokens, boosts = {}, amount = nil allocations = allocations_for tokens # Score the allocations using weights as bias. # # Note: Before we can sort them we need to score them. # allocations.calculate_score boosts # Filter the allocations – ignore/only. # allocations.keep_allocations exclusive_allocations if exclusive_allocations allocations.remove_allocations ignored_allocations if ignored_allocations # Sort the allocations. # (allocations are sorted according to score, highest to lowest) # # Before we can chop off unimportant allocations, we need to sort them. # allocations.sort! # allocations.remove_allocations ignored_allocations if ignored_allocations # Reduce the amount of allocations. # # Before we remove categories, we should reduce the amount of allocations. # allocations.reduce_to amount if amount # Remove categories from allocations. # allocations.remove_categories ignored_categories if ignored_categories allocations end |