Permalink
Browse files

adding or_search method to collection for performing multiple searche…

…s and returning matches which apply to any of them
  • Loading branch information...
ryanb committed Jul 7, 2009
1 parent 83de46f commit ac7f59efcc06f118befe4f1a228afe5253674590
View
@@ -1,3 +1,8 @@
+* chain a separate search with "or_search" to find records matching either one
+
+ search("foo").or_search(:conditions => { :priority => 3 })
+
+
*0.2.6* (July 6th, 2009)
* search for field conditions in query string, only supported by ClassicQueryParser
View
@@ -119,7 +119,6 @@ Scenario: Query for separate OR conditions
When I query "age" matching "17" or "name" matching "Jack"
Then I should find records named "Jane, Jack"
-@focus
Scenario: Query for condition in keywords string
Given the following indexed records
| name | age |
@@ -128,3 +127,12 @@ Scenario: Query for condition in keywords string
| Jack | 17 |
When I query for "age:17"
Then I should find records named "Jane, Jack"
+
+Scenario: Query for separate OR conditions and keywords
+ Given the following indexed records
+ | name | age |
+ | John | 23 |
+ | Jane | 17 |
+ | Jack | 18 |
+ When I query for "John" or "age" matching "18" ordered by "name"
+ Then I should find records named "Jack, John"
@@ -78,6 +78,10 @@
@records = XapitMember.search(:conditions => [{ field1.to_sym => value1 }, { field2.to_sym => value2 }])
end
+When /^I query for "([^\"]*)" or "([^\"]*)" matching "([^\"]*)" ordered by "([^\"]*)"$/ do |keywords, field, value, order|
+ @records = XapitMember.search(keywords, :order => order).or_search(:conditions => { field.to_sym => value })
+end
+
When /^I query "([^\"]*)" between (\d+) and (\d+)$/ do |field, beginning, ending|
@records = XapitMember.search(:conditions => { field.to_sym => beginning.to_i..ending.to_i })
end
View
@@ -56,12 +56,32 @@ def last
# Perform another search on this one, inheriting all options already passed.
# See Xapit::Membership for search options.
- def search(keywords, options = {})
- collection = Collection.new(@query_parser.member_class, keywords, options)
+ #
+ # Article.search("kite").search("sky") # only performs one query
+ #
+ def search(*args)
+ collection = Collection.new(@query_parser.member_class, *args)
collection.base_query = @query_parser.query
collection
end
+ # Chain another search returning all records matched by either this search or the previous search
+ # Inherits all options passed in earlier search (such as :page and :order)
+ # See Xapit::Membership for search options.
+ #
+ # Article.search("kite").or_search(:conditions => { :priority => 1 })
+ #
+ def or_search(*args)
+ collection = Collection.new(@query_parser.member_class, *args)
+ collection.base_query = @query_parser.base_query.dup # TODO duplication is necessary here because query is later modified, maybe I should make query immutable.
+ collection.extra_queries << @query_parser.query
+ collection
+ end
+
+ def query
+ @query_parser.query
+ end
+
def base_query=(base_query)
@query_parser.base_query = base_query
end
@@ -70,6 +90,14 @@ def base_query
@query_parser.base_query
end
+ def extra_queries=(extra_queries)
+ @query_parser.extra_queries = extra_queries
+ end
+
+ def extra_queries
+ @query_parser.extra_queries
+ end
+
# The page number we are currently on.
def current_page
@query_parser.current_page
@@ -2,14 +2,24 @@ module Xapit
class AbstractQueryParser
attr_reader :member_class
attr_writer :base_query
+ attr_accessor :extra_queries
def initialize(*args)
@options = args.extract_options!
@member_class = args[0]
@search_text = args[1].to_s
+ @extra_queries = []
end
def query
+ if @extra_queries.blank?
+ primary_query
+ else
+ primary_query.or_query(@extra_queries, :or)
+ end
+ end
+
+ def primary_query
if (@search_text.split + condition_terms + not_condition_terms + facet_terms).empty?
base_query
else

0 comments on commit ac7f59e

Please sign in to comment.