Permalink
Browse files

+ Experimental implementation of ignore and only

  • Loading branch information...
floere committed Dec 28, 2012
1 parent e02728b commit 38b496187336bbd675308058cb71d6baf4042d42
@@ -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.
@@ -113,6 +113,12 @@ def to_result
def to_json options = {}
MultiJson.encode to_result, options
end
+
+ #
+ #
+ def to_qualifiers
+ @combinations.to_qualifiers
+ end
#
#
@@ -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.
#
@@ -49,6 +49,10 @@ def remove categories = []
def to_result
@combinations.map &:to_result
end
+
+ def to_qualifiers
+ @combinations.map &:category_name
+ end
#
#
@@ -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.
#
@@ -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.
@@ -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
@@ -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
@@ -1,45 +0,0 @@
-module Picky
-
- module Query
-
- class IndexesCheck
-
- 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
View
@@ -23,9 +23,7 @@ class Search
attr_accessor :tokenizer,
:boosts
- forward :ignore,
- :only,
- :remap_qualifiers,
+ forward :remap_qualifiers,
:to => :indexes
# Takes:
@@ -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
Oops, something went wrong.

0 comments on commit 38b4961

Please sign in to comment.