Skip to content

Commit

Permalink
adding or_search method to collection for performing multiple searche…
Browse files Browse the repository at this point in the history
…s and returning matches which apply to any of them
  • Loading branch information
ryanb committed Jul 7, 2009
1 parent 83de46f commit ac7f59e
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 3 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
@@ -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
Expand Down
10 changes: 9 additions & 1 deletion features/finding.feature
Original file line number Diff line number Diff line change
Expand Up @@ -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 |
Expand All @@ -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"
4 changes: 4 additions & 0 deletions features/step_definitions/xapit_steps.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
32 changes: 30 additions & 2 deletions lib/xapit/collection.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
10 changes: 10 additions & 0 deletions lib/xapit/query_parsers/abstract_query_parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit ac7f59e

Please sign in to comment.