Module: SolrMapper::SolrDocument::ClassMethods

Defined in:
lib/solr_mapper/locators.rb,
lib/solr_mapper/relations.rb,
lib/solr_mapper/calculations.rb,
lib/solr_mapper/solr_document.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#base_urlObject

Returns the value of attribute base_url.



24
25
26
# File 'lib/solr_mapper/solr_document.rb', line 24

def base_url
  @base_url
end

#has_many_relationshipsObject

Returns the value of attribute has_many_relationships.



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

def has_many_relationships
  @has_many_relationships
end

#per_pageObject

Returns the value of attribute per_page.



25
26
27
# File 'lib/solr_mapper/solr_document.rb', line 25

def per_page
  @per_page
end

#solr_fieldsObject

Returns the value of attribute solr_fields.



26
27
28
# File 'lib/solr_mapper/solr_document.rb', line 26

def solr_fields
  @solr_fields
end

Instance Method Details

#auto_generate_idObject



41
42
43
# File 'lib/solr_mapper/solr_document.rb', line 41

def auto_generate_id
  @auto_geneerate_id = true
end

#auto_generate_id?Boolean

Returns:

  • (Boolean)


45
46
47
# File 'lib/solr_mapper/solr_document.rb', line 45

def auto_generate_id?
  @auto_geneerate_id
end

#belongs_to(target_name, opts = {}) ⇒ Object

handle a belongs to relation. target index contains document with foreign keys to this document



153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
# File 'lib/solr_mapper/relations.rb', line 153

def belongs_to(target_name, opts = {})
  target_id_field_name = foreign_key(self.name)

  class_eval do
    # create getter for owner object
    define_method target_name do
      owner = instance_variable_get("@#{target_name}")

      unless owner
        # owner object hasn't been lazy loaded.  do so now.
        owner = Object::const_get(classify(target_name)).query(target_id_field_name => instance_variable_get("@_id"))[0]
        instance_variable_set("@#{target_name}", owner)
      end
      
      owner
    end

    # create setter for owner object
    define_method "#{target_name}=" do |val|
      instance_variable_set("@#{target_name}", val)
      val.instance_variable_set("@#{target_id_field_name}", instance_variable_get("@_id"))
      val.save()            
    end
  end
end

#bind_service_url(val) ⇒ Object



32
33
34
35
# File 'lib/solr_mapper/solr_document.rb', line 32

def bind_service_url(val)
  @base_url = val
  @base_url = ActiveSupport::HashWithIndifferentAccess.new(@base_url) if @base_url.instance_of?(Hash)
end

#build_qs(opts) ⇒ Object

create a querystring from a hash



82
83
84
85
86
87
88
89
90
91
92
# File 'lib/solr_mapper/solr_document.rb', line 82

def build_qs(opts)
  uri = ''

  if opts
    opts.each_pair do |k, v|
      uri << "#{k}=#{v}&"
    end
  end

  uri.chop
end

#build_url(path, opts = nil) ⇒ Object



67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/solr_mapper/solr_document.rb', line 67

def build_url(path, opts = nil)
  qs = build_qs(opts)
  qs = '?' + qs unless qs.empty?

  if self.base_url.kind_of?(Hash) && ENV['RAILS_ENV']
    self.base_url = ActiveSupport::HashWithIndifferentAccess.new(self.base_url) unless self.base_url.kind_of?(ActiveSupport::HashWithIndifferentAccess)
    base = self.base_url[ENV['RAILS_ENV']]
  else
    base = base_url
  end

  URI::escape("#{base}/#{path}#{qs}")
end

#count(search = nil) ⇒ Object



18
19
20
21
22
# File 'lib/solr_mapper/calculations.rb', line 18

def count(search = nil)
  search ||= '*:*'
  _, ct = query_counted(search, {:rows => 0})
  ct
end

#execute_read(opts) ⇒ Object

send a read REST command to Solr



50
51
52
53
# File 'lib/solr_mapper/solr_document.rb', line 50

def execute_read(opts)
  url = build_url('select', opts.merge(:wt => 'ruby'))
  eval(RestClient.get(url))
end

#execute_write(data, opts = nil) ⇒ Object

send a write REST command to Solr



56
57
58
59
60
61
62
63
64
65
# File 'lib/solr_mapper/solr_document.rb', line 56

def execute_write(data, opts = nil)
  send_update(data, opts)
  
  # make an xml commit message Solr will be happy with
  commit_message = ''
  builder = Builder::XmlMarkup.new(:target => commit_message, :indent => 2)
  builder.commit('waitFlush' => true, 'waitSearcher' => true)

  send_update(commit_message)
end

#find(id) ⇒ Object

look up an object by primary key



131
132
133
134
# File 'lib/solr_mapper/solr_document.rb', line 131

def find(id)
  result = query(:id => id)
  return result[0] if result.count > 0
end

#first(search_query = '*:*', opts = {}) ⇒ Object



18
19
20
21
22
# File 'lib/solr_mapper/locators.rb', line 18

def first(search_query = '*:*', opts = {})
  results = query(search_query, opts)

  results[0]
end

#has_many(target, opts = {}) ⇒ Object

handle a has one relationship. this document contains a foreign key to another index’s documents



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
# File 'lib/solr_mapper/relations.rb', line 43

def has_many(target, opts = {})
  class_name, field_name, variable_name, id_field = determine_names(target, opts)
  @@facet_field_name = field_name
  has_many_relationships[field_name.to_s] = id_field

  # add class method for loading relations via facets
  class << self
    define_method "#{@@facet_field_name}_facet" do |search|
      fk =  has_many_relationships[__method__.to_s.gsub(/_facet$/, '')]

      solr_results = raw_query(search, {'facet' => 'true', 'facet.field' => fk})
      klass = Object::const_get(classify(singularize(__method__.to_s.gsub(/_facet$/, ''))))
      results = {}

      solr_results['facet_counts']['facet_fields'][fk].each_slice(2).each do |pair|
        child = klass.find(pair[0])
        results[child] = pair[1] if child
      end

      results
    end
  end

  @@facet_field_name = nil

  # add a helper method that we'll use to hook arrays with manipulation logic we need
  class_eval do
    def relationize_array(array)
      class << array
        alias :super_push :push
        alias :super_delete :delete

        def << val
          val.save
          push val
          @owner.save()
        end

        def push val
          super_push val
          @owner.refresh_relation(instance_variable_get("@field_name"))
        end

        def destroy val
          val.destroy
          delete val
        end

        def delete val
          super_delete val
          @owner.refresh_relation(instance_variable_get("@field_name"))
        end
      end

      array
    end

    # define a getter for this relation
    define_method field_name do
      val = instance_variable_get(variable_name)

      unless val
        ids = instance_variable_get("@#{id_field}")
        val = []

        val.instance_variable_set("@owner", self)
        val.instance_variable_set("@field_name", field_name.to_s)

        unless ids
          instance_variable_set("@#{id_field}", [])
          ids = instance_variable_get("@#{id_field}")
        end

        ids.each do |id|
          val << Object::const_get(class_name).find(id)
        end

        # patch this array up so it does the callbacks we need
        relationize_array(val)

        instance_variable_set(variable_name, val)
      end

      val
    end

    # define a setter for this relation
    define_method "#{field_name}=" do |vals|
      ids = []

      if self.class.instance_variable_get('@solr_fields').include?(field_name)
        self.class.instance_variable_get('@solr_fields') << field_name
      end

      if vals
        vals.each do |obj|
          ids << obj._id
        end

        # if we didnt' create this array we'll have to patch it up to deal with our callbacks & patching
        relationize_array(vals) unless vals.respond_to?(:destroy)
      end

      instance_variable_set("@#{id_field}", ids)
      instance_variable_set("@#{field_name}", val)
    end
  end
end

#has_one(target, opts = {}) ⇒ Object

handle a has one relationship. this document contains a foreign key to a doc in another index



21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/solr_mapper/relations.rb', line 21

def has_one(target, opts = {})
  class_name, field_name, variable_name, id_field = determine_names(target, opts)

  class_eval do
    define_method field_name do
      val = instance_variable_get(variable_name)

      unless val
        id = instance_variable_get("@#{id_field}")
        val = Object::const_get(class_name).find(id) if id
      end

      val
    end

    define_method "#{field_name}=" do |val|
      instance_variable_set("@#{field_name}", val)
    end
  end
end

#limit_page_size(val) ⇒ Object



28
29
30
# File 'lib/solr_mapper/solr_document.rb', line 28

def limit_page_size(val)
   @per_page = val
end

#paginate(search_query, opts = {}) ⇒ Object

return will_paginate pages for search queries



137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# File 'lib/solr_mapper/solr_document.rb', line 137

def paginate(search_query, opts = {})
  opts[:page] ||= 1
  opts[:page] = opts[:page].to_i if opts[:page].respond_to?(:to_i)
  opts[:rows] ||= per_page || 10
  opts[:start] = (opts[:page] - 1) * opts[:rows]

  WillPaginate::Collection.create(opts[:page], opts[:rows]) do |pager|
    results, count = query_counted(search_query, opts)

    if results
      results.compact!

      pager.total_entries = count
      pager.replace(results)
      return pager
    end          
  end
end

#query(values, opts = {}) ⇒ Object

main interface by which consumers search solr via SolrMapper



102
103
104
105
# File 'lib/solr_mapper/solr_document.rb', line 102

def query(values, opts = {})
  results, _ = query_counted(values, opts)
  results
end

#query_counted(values, opts = {}) ⇒ Object

execute solr query and return the count as well as OBJECTS



125
126
127
128
# File 'lib/solr_mapper/solr_document.rb', line 125

def query_counted(values, opts = {})
  response = raw_query(values, opts)
  return map(response), response['response']['numFound']
end

#raw_query(values, opts = {}) ⇒ Object

execute solr query and return the count as well as the RAW results



108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/solr_mapper/solr_document.rb', line 108

def raw_query(values, opts = {})
  if values.kind_of?(Hash)
    search_string = ''

    values.each_pair do |k, v|
      search_string << "#{k}:#{v} "
    end

    search_string = search_string.chop
  else
    search_string = values.to_s
  end

  execute_read(opts.merge(:q => search_string))
end

#search(values, opts = {}) ⇒ Object



94
95
96
97
98
99
# File 'lib/solr_mapper/solr_document.rb', line 94

def search(values, opts = {})
  puts "Warning, the search method is deprecated and will be removed in a future release."
  puts "Instead use 'query' which can accept a string."

  query(values, opts)
end

#service_urlObject



37
38
39
# File 'lib/solr_mapper/solr_document.rb', line 37

def service_url
  @base_url
end