Class: Cloudsearchable::Domain

Inherits:
Object
  • Object
show all
Defined in:
lib/cloudsearchable/domain.rb

Defined Under Namespace

Classes: DomainNotFound

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name) ⇒ Domain

Returns a new instance of Domain.



12
13
14
15
# File 'lib/cloudsearchable/domain.rb', line 12

def initialize name
  @name = "#{Cloudsearchable::Config.domain_prefix}#{name}"
  @fields = {}
end

Instance Attribute Details

#fieldsObject (readonly)

Returns the value of attribute fields.



10
11
12
# File 'lib/cloudsearchable/domain.rb', line 10

def fields
  @fields
end

#nameObject (readonly)

Returns the value of attribute name.



10
11
12
# File 'lib/cloudsearchable/domain.rb', line 10

def name
  @name
end

Instance Method Details

#add_field(name, type, options = {}) ⇒ Object

Defines a literal index field.

Parameters:

  • name

    field name

  • type

    field type - one of :literal, :uint, or :text

  • options (Hash) (defaults to: {})

    a customizable set of options

Options Hash (options):

  • :search_enabled (Boolean) — default: true
  • :return_enabled (Boolean) — default: true
  • :source (Symbol or Proc)

    The name of a method to call on a record to fetch the value of the field, or else a Proc to be evaluated in the context of the record. Defaults to a method with the same name as the field.



25
26
27
28
29
# File 'lib/cloudsearchable/domain.rb', line 25

def add_field(name, type, options = {})
  field = Field.new(name, type, options)
  raise "Field #{name} already exists on index #{self.name}" if @fields.has_key?(field.name)
  @fields[field.name] = field
end

#addition_sdf(record, record_id, version) ⇒ Object



109
110
111
112
113
114
115
116
117
# File 'lib/cloudsearchable/domain.rb', line 109

def addition_sdf record, record_id, version
  {
    :type    => "add",
    :id      => document_id(record_id),
    :version => version,
    :lang    => "en", # FIXME - key off of marketplace
    :fields  => sdf_fields(record)
  }
end

#apply_changes(timeout = 0) ⇒ Object

This queries the status of the domain from Cloudsearch and determines if the domain needs to be reindexed. If so, it will initiate the reindex and wait timeout seconds for it to complete. Default is 0. Reindexings tend to take 15-30 minutes.

Returns:

  • true if the changes are applied, false if the domain is still reindexing



57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/cloudsearchable/domain.rb', line 57

def apply_changes(timeout = 0)
  d = cloudsearch_domain(true)[:domain_status_list][0]
  if(d[:requires_index_documents])
    reindex
  end
  
  #We'll potentially sleep until the reindex has completed
  end_time = Time.now + timeout
  sleep_time = 1
  loop do
    d = cloudsearch_domain(true)[:domain_status_list][0]
    break unless (d[:processing] && Time.now < end_time)
    
    sleep(sleep_time)          
    sleep_time = [2 * sleep_time, end_time - Time.now].min #exponential backoff
  end
  
  !d[:processing] #processing is true as long as it is reindexing
end

#createObject

Creates the domain and defines its index fields in Cloudsearch Will blindly recreate index fields, no-op if the index already exists



33
34
35
36
37
38
39
40
41
42
43
# File 'lib/cloudsearchable/domain.rb', line 33

def create
  Cloudsearchable.logger.info "Creating domain #{name}"
  CloudSearch.client.create_domain(:domain_name => name)

  #Create the fields for the index
  fields.values.each do |field| 
    Cloudsearchable.logger.info "  ...creating #{field.type} field #{name}"
    field.define_in_domain self.name
  end
  Cloudsearchable.logger.info "  ...done!"
end

#delete_record(record_id, version) ⇒ Object

Delete the CloudSearch document for a particular record (version must be greater than the last version pushed)



85
86
87
88
89
# File 'lib/cloudsearchable/domain.rb', line 85

def delete_record record_id, version
  ActiveSupport::Notifications.instrument('cloudsearchable.delete_record') do
    CloudSearch.post_sdf doc_endpoint, deletion_sdf(record_id, version)
  end
end

#deletion_sdf(record_id, version) ⇒ Object



101
102
103
104
105
106
107
# File 'lib/cloudsearchable/domain.rb', line 101

def deletion_sdf record_id, version
  {
    :type    => "delete",
    :id      => document_id(record_id),
    :version => version
  }
end

#document_id(record_id) ⇒ Object

Generate a documentID that follows the CS restrictions



120
121
122
# File 'lib/cloudsearchable/domain.rb', line 120

def document_id record_id
  Digest::MD5.hexdigest record_id.to_s
end

#execute_query(params) ⇒ Object



91
92
93
94
95
96
97
98
99
# File 'lib/cloudsearchable/domain.rb', line 91

def execute_query(params)
  uri    = URI("http://#{search_endpoint}/#{CloudSearch::API_VERSION}/search")
  uri.query = URI.encode_www_form(params)
  Cloudsearchable.logger.info "CloudSearch execute: #{uri.to_s}"
  res = ActiveSupport::Notifications.instrument('cloudsearchable.execute_query') do
    Net::HTTP.get_response(uri).body
  end
  JSON.parse(res)
end

#post_record(record, record_id, version) ⇒ Object

Add or replace the CloudSearch document for a particular version of a record



78
79
80
81
82
# File 'lib/cloudsearchable/domain.rb', line 78

def post_record record, record_id, version
  ActiveSupport::Notifications.instrument('cloudsearchable.post_record') do
    CloudSearch.post_sdf doc_endpoint, addition_sdf(record, record_id, version)
  end
end

#reindexObject



45
46
47
# File 'lib/cloudsearchable/domain.rb', line 45

def reindex
  CloudSearch.client.index_documents(:domain_name => name)
end