Skip to content

Commit

Permalink
+ Experimental implementation of ignore and only
Browse files Browse the repository at this point in the history
  • Loading branch information
floere committed Dec 28, 2012
1 parent e02728b commit 38b4961
Show file tree
Hide file tree
Showing 13 changed files with 288 additions and 78 deletions.
2 changes: 1 addition & 1 deletion server/lib/picky/loader.rb
Expand Up @@ -173,7 +173,7 @@ def load_query
load_relative 'query/boosts'

load_relative 'query/indexes',
'query/indexes_check'
'query/indexes/check'
end

# Loads the internal parts of the framework.
Expand Down
6 changes: 6 additions & 0 deletions server/lib/picky/query/allocation.rb
Expand Up @@ -113,6 +113,12 @@ def to_result
def to_json options = {}
MultiJson.encode to_result, options
end

#
#
def to_qualifiers
@combinations.to_qualifiers
end

#
#
Expand Down
37 changes: 35 additions & 2 deletions server/lib/picky/query/allocations.rb
Expand Up @@ -46,13 +46,46 @@ def reduce_to amount
@allocations = @allocations.shift amount
end

# Removes combinations.
# Removes categories from allocations.
#
# Only those passed in are removed.
#
def remove categories = []
def remove_categories categories = []
@allocations.each { |allocation| allocation.remove categories } unless categories.empty?
end

# Removes allocations.
#
# Only those passed in are removed.
#
# TODO Rewrite, speed up.
#
def remove_allocations qualifiers_array = []
return if qualifiers_array.empty?
@allocations.select! do |allocation|
allocation_qualifiers = allocation.combinations.to_qualifiers
next(false) if qualifiers_array.any? do |qualifiers|
allocation_qualifiers == qualifiers
end
allocation
end
end

# Keeps allocations.
#
# Only those passed in are kept.
#
# TODO Rewrite, speed up.
#
def keep_allocations qualifiers_array = []
return if qualifiers_array.empty?
@allocations.select! do |allocation|
allocation_qualifiers = allocation.combinations.to_qualifiers
next(true) if qualifiers_array.any? do |qualifiers|
allocation_qualifiers == qualifiers
end
end
end

# Returns the top amount ids.
#
Expand Down
4 changes: 4 additions & 0 deletions server/lib/picky/query/combinations.rb
Expand Up @@ -49,6 +49,10 @@ def remove categories = []
def to_result
@combinations.map &:to_result
end

def to_qualifiers
@combinations.map &:category_name
end

#
#
Expand Down
61 changes: 41 additions & 20 deletions server/lib/picky/query/indexes.rb
Expand Up @@ -16,35 +16,49 @@ class Indexes
forward :size, :first, :to => :@indexes

attr_reader :indexes,
:ignored_categories
:ignored_categories,
:ignored_allocations,
:exclusive_allocations

# Creates a new Query::Indexes.
#
# Its job is to generate all possible combinations.
# Note: We cannot mix memory and redis indexes just yet.
#
def initialize *indexes
IndexesCheck.check_backends indexes
Check.check_backends indexes

@indexes = indexes
end

# TODO Reinstate.
#
# # Ignore the categories with these qualifiers.
# #
# # Example:
# # search = Search.new(index1, index2, index3) do
# # ignore :name, :first_name
# # end
# #
# # Note: Cleans up / optimizes after being called.
# #
# def ignore *qualifiers
# @ignored_categories ||= []
# @ignored_categories += qualifiers.map { |qualifier| @qualifier_mapper.map qualifier }.compact
# @ignored_categories.uniq!
# end
# Ignore the categories with the given qualifiers.
#
def ignore_categories *qualifiers
@ignored_categories ||= []
# @ignored_categories += qualifiers.map { |qualifier| @qualifier_mapper.map qualifier }.compact
@ignored_categories += qualifiers
@ignored_categories.uniq!
end

# Ignore the allocations with the given qualifiers.
#
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

# Exclusively keep the allocations with the given qualifiers.
#
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

# Returns a number of prepared (sorted, reduced etc.) allocations for the given tokens.
#
Expand All @@ -57,13 +71,20 @@ def prepared_allocations_for tokens, weights = {}, amount = nil
#
allocations.calculate_score weights

# 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.
Expand All @@ -72,7 +93,7 @@ def prepared_allocations_for tokens, weights = {}, amount = nil

# Remove categories from allocations.
#
allocations.remove ignored_categories if ignored_categories
allocations.remove_categories ignored_categories if ignored_categories

allocations
end
Expand Down
51 changes: 51 additions & 0 deletions server/lib/picky/query/indexes/check.rb
@@ -0,0 +1,51 @@
module Picky

module Query

class Indexes

#
#
class Check

class << self

# Returns the right combinations strategy for
# a number of query indexes.
#
# Currently it isn't possible using Memory and Redis etc.
# indexes in the same query index group.
#
# Picky will raise a Query::Indexes::DifferentBackendsError.
#
def check_backends indexes
backends = indexes.map &:backend
backends.uniq! &:class
raise_different backends if backends.size > 1
backends
end
def raise_different backends
raise DifferentBackendsError.new(backends)
end

end

end

# Currently it isn't possible using Memory and Redis etc.
# indexes in the same query index group.
#
class DifferentBackendsError < StandardError
def initialize backends
@backends = backends
end
def to_s
"Currently it isn't possible to mix Indexes with backends #{@backends.join(" and ")} in the same Search instance."
end
end

end

end

end
45 changes: 0 additions & 45 deletions server/lib/picky/query/indexes_check.rb

This file was deleted.

39 changes: 35 additions & 4 deletions server/lib/picky/search.rb
Expand Up @@ -23,9 +23,7 @@ class Search
attr_accessor :tokenizer,
:boosts

forward :ignore,
:only,
:remap_qualifiers,
forward :remap_qualifiers,
:to => :indexes

# Takes:
Expand Down Expand Up @@ -140,7 +138,40 @@ def terminate_early extra_allocations = 0
def boost boosts
@boosts = extract_boosts boosts
end


# Ignore given categories and/or combinations of
# categories.
#
# Example:
# search = Search.new(people) do
# ignore :name,
# :first_name
# [:last_name, :street]
# end
#
def ignore *allocations_and_categories
allocations_and_categories.each do |allocation_or_category|
if allocation_or_category.respond_to? :to_sym
indexes.ignore_categories allocation_or_category
else
indexes.ignore_allocations allocation_or_category
end
end
end

# Exclusively keep combinations of
# categories.
#
# Example:
# search = Search.new(people) do
# only [:last_name, :street],
# [:last_name, :first_name]
# end
#
def only *allocations_and_categories
indexes.keep_allocations *allocations_and_categories
end

# Ignore the given token if it cannot be matched to a category.
# The default behaviour is that if a token does not match to
# any category, the query will not return anything (since a
Expand Down

0 comments on commit 38b4961

Please sign in to comment.