Class: Asari

Inherits:
Object
  • Object
show all
Defined in:
lib/asari.rb,
lib/asari/version.rb,
lib/asari/geography.rb,
lib/asari/collection.rb,
lib/asari/exceptions.rb,
lib/asari/active_record.rb

Defined Under Namespace

Modules: ActiveRecord, Geography Classes: Collection, DocumentUpdateException, MissingSearchDomainException, SearchException

Constant Summary collapse

VERSION =
"0.13.0"

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(search_domain = nil, aws_region = nil) ⇒ Asari

Returns a new instance of Asari.



26
27
28
29
# File 'lib/asari.rb', line 26

def initialize(search_domain=nil, aws_region=nil)
  @search_domain = search_domain
  @aws_region = aws_region
end

Instance Attribute Details

#api_versionObject

Public: returns the current api_version, or the sensible default of “2011-02-01” (at the time of writing, the current version of the CloudSearch API).



42
43
44
# File 'lib/asari.rb', line 42

def api_version
  @api_version || "2011-02-01"
end

#aws_regionObject

Public: returns the current aws_region, or the sensible default of “us-east-1.”



48
49
50
# File 'lib/asari.rb', line 48

def aws_region
  @aws_region || "us-east-1"
end

#search_domainObject

Public: returns the current search_domain, or raises a MissingSearchDomainException.



34
35
36
# File 'lib/asari.rb', line 34

def search_domain
  @search_domain || raise(MissingSearchDomainException.new)
end

Class Method Details

.modeObject



14
15
16
# File 'lib/asari.rb', line 14

def self.mode
  @@mode
end

.mode=(mode) ⇒ Object



18
19
20
# File 'lib/asari.rb', line 18

def self.mode=(mode)
  @@mode = mode
end

Instance Method Details

#add_item(id, fields) ⇒ Object

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.

Examples:

@asari.update_item("4", { :name => "Party Pooper", :email => ..., ... }) #=> nil

Returns: nil if the request is successful.

Raises: DocumentUpdateException if there’s an issue communicating the

request to the server.


126
127
128
129
130
131
132
133
134
135
136
# File 'lib/asari.rb', line 126

def add_item(id, fields)
  return nil if self.class.mode == :sandbox
  query = { "type" => "add", "id" => id.to_s, "version" => Time.now.to_i, "lang" => "en" }
  fields.each do |k,v|
    fields[k] = convert_date_or_time(fields[k])
    fields[k] = "" if v.nil?
  end

  query["fields"] = fields
  doc_request(query)
end

#doc_request(query) ⇒ Object

Internal: helper method: common logic for queries against the doc endpoint.



179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
# File 'lib/asari.rb', line 179

def doc_request(query)
  endpoint = "http://doc-#{search_domain}.#{aws_region}.cloudsearch.amazonaws.com/#{api_version}/documents/batch"

  options = { :body => [query].to_json, :headers => { "Content-Type" => "application/json"} }

  begin
    response = HTTParty.post(endpoint, options)
  rescue Exception => e
    ae = Asari::DocumentUpdateException.new("#{e.class}: #{e.message}")
    ae.set_backtrace e.backtrace
    raise ae
  end

  unless response.response.code == "200"
    raise Asari::DocumentUpdateException.new("#{response.response.code}: #{response.response.msg}")
  end

  nil
end

#remove_item(id) ⇒ Object

Public: Remove an item from the index based on its document ID.

Examples:

@asari.search("fritters") #=> ["13","28"]
@asari.remove_item("13") #=> nil
@asari.search("fritters") #=> ["28"]
@asari.remove_item("13") #=> nil

Returns: nil if the request is successful (note that asking the index to

delete an item that's not present in the index is still a successful
request).

Raises: DocumentUpdateException if there’s an issue communicating the

request to the server.


170
171
172
173
174
175
# File 'lib/asari.rb', line 170

def remove_item(id)
  return nil if self.class.mode == :sandbox

  query = { "type" => "delete", "id" => id.to_s, "version" => Time.now.to_i }
  doc_request query
end

#search(term, options = {}) ⇒ Object

Public: Search for the specified term.

Examples:

@asari.search("fritters") #=> ["13","28"]
@asari.search(filter: { and: { type: 'donuts' }}) #=> ["13,"28","35","50"]
@asari.search(filter: "(or type:'donut' type:'bagel')")  #=> ["13,"28","35","50", "80"]
@asari.search("fritters", filter: { and: { type: 'donuts' }}) #=> ["13"]

Returns: An Asari::Collection containing all document IDs in the system that match the

specified search term. If no results are found, an empty Asari::Collection is
returned.

Raises: SearchException if there’s an issue communicating the request to

the server.


67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/asari.rb', line 67

def search(term, options = {})
  return Asari::Collection.sandbox_fake if self.class.mode == :sandbox
  term,options = "",term if term.is_a?(Hash) and options.empty?

  bq = if options[:filter]
    if options[:filter].is_a?(String)
      options[:filter]
    else
      boolean_query(options[:filter])
    end
  end
  page_size = options[:page_size].nil? ? 10 : options[:page_size].to_i

  url = "http://search-#{search_domain}.#{aws_region}.cloudsearch.amazonaws.com/#{api_version}/search"
  url += "?q=#{CGI.escape(term.to_s)}"
  url += "&bq=#{CGI.escape(bq)}" if options[:filter]
  url += "&size=#{page_size}"
  url += "&return-fields=#{options[:return_fields].join ','}" if options[:return_fields]

  if options[:page]
    start = (options[:page].to_i - 1) * page_size
    url << "&start=#{start}"
  end

  if options[:rank]
    rank = normalize_rank(options[:rank])
    url << "&rank=#{rank}"
  end

  begin
    response = HTTParty.get(url)
  rescue Exception => e
    ae = Asari::SearchException.new("#{e.class}: #{e.message} (#{url})")
    ae.set_backtrace e.backtrace
    raise ae
  end

  unless response.response.code == "200"
    raise Asari::SearchException.new("#{response.response.code}: #{response.response.msg} (#{url})")
  end

  Asari::Collection.new(response, page_size)
end

#update_item(id, fields) ⇒ Object

Public: Update an item in the index based on its document ID.

Note: As of right now, this is the same method call in CloudSearch
that's utilized for adding items. This method is here to provide a
consistent interface in case that changes.

Examples:

@asari.update_item("4", { :name => "Party Pooper", :email => ..., ... }) #=> nil

Returns: nil if the request is successful.

Raises: DocumentUpdateException if there’s an issue communicating the

request to the server.


152
153
154
# File 'lib/asari.rb', line 152

def update_item(id, fields)
  add_item(id, fields)
end