Skip to content

Commit

Permalink
Boolean search queries
Browse files Browse the repository at this point in the history
  • Loading branch information
kaiuhl committed Sep 9, 2013
1 parent e4d32b5 commit d7e8811
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 8 deletions.
29 changes: 28 additions & 1 deletion lib/asari.rb
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,35 @@ def search(term, options = {})
Asari::Collection.new(response, page_size)
end

# Public: Search using boolean queries. Builds the query from a passed hash and
# calls search.
#
# terms - a hash of the search query. %w(and or not) are reserved hash keys
# that build the logic of the query
#
# Examples:
#
# @asari.boolean_search(and: { name: "fritters", type: "donut" }) #=> ["13", "28"]
#
def boolean_search(terms = {}, options = {})
reduce = lambda { |hash|
hash.reduce("") do |memo, (key, value)|
if %w(and or not).include?(key.to_s) && value.is_a?(Hash)
memo += "(#{key}#{reduce.call(value)})"
else
memo += " #{key}:'#{value}'" unless value.to_s.nil? || value.to_s.empty?
end
end
}

query = reduce.call(terms)

search(query, options.merge(:query_type => :boolean))
end


# Public: Add an item to the index with the given ID.
#
#
# id - the ID to associate with this document
# fields - a hash of the data to associate with this document. This
# needs to match the search fields defined in your CloudSearch domain.
Expand Down
2 changes: 1 addition & 1 deletion lib/asari/collection.rb
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ def replace(array)
end

def class
Asari::Collection
::Asari::Collection
end

def method_missing(method, *args, &block)
Expand Down
35 changes: 29 additions & 6 deletions spec/search_spec.rb
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
require_relative "../spec_helper"

describe Asari do
describe "searching" do
before :each do
@asari = Asari.new("testdomain")
stub_const("HTTParty", double())
HTTParty.stub(:get).and_return(fake_response)
end
before :each do
@asari = Asari.new("testdomain")
stub_const("HTTParty", double())
HTTParty.stub(:get).and_return(fake_response)
end

describe "searching" do
context "when region is not specified" do
it "allows you to search using default region." do
HTTParty.should_receive(:get).with("http://search-testdomain.us-east-1.cloudsearch.amazonaws.com/2011-02-01/search?q=testsearch&size=10")
Expand Down Expand Up @@ -118,4 +118,27 @@

end

describe "boolean searching" do
it "builds a query string from a passed hash" do
HTTParty.should_receive(:get).with("http://search-testdomain.us-east-1.cloudsearch.amazonaws.com/2011-02-01/search?bq=%28and+foo%3A%27bar%27+baz%3A%27bug%27%29&size=10")
@asari.boolean_search(and: { foo: "bar", baz: "bug" })
end

it "honors the logic types" do
HTTParty.should_receive(:get).with("http://search-testdomain.us-east-1.cloudsearch.amazonaws.com/2011-02-01/search?bq=%28or+foo%3A%27bar%27+baz%3A%27bug%27%29&size=10")
@asari.boolean_search(or: { foo: "bar", baz: "bug" })
end

it "supports nested logic" do
HTTParty.should_receive(:get).with("http://search-testdomain.us-east-1.cloudsearch.amazonaws.com/2011-02-01/search?bq=%28or+is_donut%3A%27true%27%28and+round%3A%27true%27+frosting%3A%27true%27+fried%3A%27true%27%29%29&size=10")
@asari.boolean_search(or: {
is_donut: true,
and: {
round: true,
frosting: true,
fried: true
}
})
end
end
end

0 comments on commit d7e8811

Please sign in to comment.