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.10.4"

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.


119
120
121
122
123
124
125
126
127
128
129
# File 'lib/asari.rb', line 119

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.



172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
# File 'lib/asari.rb', line 172

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.


163
164
165
166
167
168
# File 'lib/asari.rb', line 163

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("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.


66
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
# File 'lib/asari.rb', line 66

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 = boolean_query(options[:filter]) if options[:filter]
  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.


145
146
147
# File 'lib/asari.rb', line 145

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