Class: Supernova::SolrIndexer

Inherits:
Object
  • Object
show all
Includes:
Solr
Defined in:
lib/supernova/solr_indexer.rb

Constant Summary collapse

FIELD_SUFFIX_MAPPING =
{
  :raw => nil,
  :string => :s,
  :text => :t,
  :int => :i,
  :integer => :i,
  :sint => :si,
  :float => :f,
  :date => :dt,
  :boolean => :b,
  :location => :p
}

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Solr

connection, included, truncate!

Constructor Details

#initialize(options = {}) ⇒ SolrIndexer

Returns a new instance of SolrIndexer.



54
55
56
57
58
59
60
# File 'lib/supernova/solr_indexer.rb', line 54

def initialize(options = {})
  options.each do |key, value|
    self.send(:"#{key}=", value) if self.respond_to?(:"#{key}=")
  end
  self.options = options
  self.ids ||= :all
end

Instance Attribute Details

#dbObject

Returns the value of attribute db.



4
5
6
# File 'lib/supernova/solr_indexer.rb', line 4

def db
  @db
end

#idsObject

Returns the value of attribute ids.



4
5
6
# File 'lib/supernova/solr_indexer.rb', line 4

def ids
  @ids
end

#index_file_pathObject



150
151
152
# File 'lib/supernova/solr_indexer.rb', line 150

def index_file_path
  @index_file_path ||= File.expand_path("/tmp/index_file_#{Time.now.to_i}.json")
end

#optionsObject

Returns the value of attribute options.



4
5
6
# File 'lib/supernova/solr_indexer.rb', line 4

def options
  @options
end

Class Method Details

.clazz(class_name = :only_return) ⇒ Object



18
19
20
21
# File 'lib/supernova/solr_indexer.rb', line 18

def clazz(class_name =:only_return)
  @clazz = class_name if class_name != :only_return
  @clazz
end

.field_definitionsObject



10
11
12
# File 'lib/supernova/solr_indexer.rb', line 10

def field_definitions
  @field_definitions ||= {}
end

.has(key, attributes) ⇒ Object



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

def has(key, attributes)
  field_definitions[key] = attributes.is_a?(Hash) ? attributes : { :type => attributes }
end

.method_missing(*args) ⇒ Object



28
29
30
31
32
33
34
# File 'lib/supernova/solr_indexer.rb', line 28

def method_missing(*args)
  if search_scope.respond_to?(args.first)
    search_scope.send(*args)
  else
    super
  end
end

.search_scopeObject



36
37
38
# File 'lib/supernova/solr_indexer.rb', line 36

def search_scope
  Supernova::SolrCriteria.new(self.clazz).attribute_mapping(self.field_definitions).named_scope_class(self)
end

.solr_field_for_field_name_and_mapping(field, mapping) ⇒ Object



126
127
128
# File 'lib/supernova/solr_indexer.rb', line 126

def self.solr_field_for_field_name_and_mapping(field, mapping)
  [field, mapping && mapping[field.to_sym] ? suffix_from_type(mapping[field.to_sym][:type]) : nil].compact.join("_")
end

.suffix_from_type(type) ⇒ Object



122
123
124
# File 'lib/supernova/solr_indexer.rb', line 122

def self.suffix_from_type(type)
  FIELD_SUFFIX_MAPPING[type.to_sym]
end

.table_name(name = :only_return) ⇒ Object



23
24
25
26
# File 'lib/supernova/solr_indexer.rb', line 23

def table_name(name = :only_return)
  @table_name = name if name != :only_return
  @table_name
end

Instance Method Details

#default_fieldsObject



83
84
85
86
87
# File 'lib/supernova/solr_indexer.rb', line 83

def default_fields
  fields = ["id"]
  fields << %("#{self.class.clazz}" AS type) if self.class.clazz
  fields
end

#defined_fieldsObject



89
90
91
92
93
# File 'lib/supernova/solr_indexer.rb', line 89

def defined_fields
  self.class.field_definitions.map do |field, options|
    sql_column_from_field_and_type(field, options[:type]) if options[:virtual] != true
  end.compact
end

#do_index_file(options = {}) ⇒ Object



186
187
188
189
190
191
192
193
194
# File 'lib/supernova/solr_indexer.rb', line 186

def do_index_file(options = {})
  raise "solr not configured" if solr_url.nil?
  cmd = if options[:local]
    %(curl -s '#{solr_url}/update/json?commit=true\\&stream.file=#{index_file_path}')
  else
    %(cd #{File.dirname(index_file_path)} && curl -s '#{solr_url}/update/json?commit=true' --data-binary @#{File.basename(index_file_path)} -H 'Content-type:application/json')
  end
  Kernel.send(:`, cmd)
end

#finishObject



167
168
169
170
171
172
# File 'lib/supernova/solr_indexer.rb', line 167

def finish
  raise "nothing to index" if !stream_open?
  index_file_stream.puts("\}")
  index_file_stream.close
  do_index_file
end

#float_or_nil_when_abs_bigger_than(value, border) ⇒ Object



107
108
109
110
111
# File 'lib/supernova/solr_indexer.rb', line 107

def float_or_nil_when_abs_bigger_than(value, border)
  return nil if value.to_s.strip.length == 0
  value_f = value.to_f
  value_f.abs > border ? nil : value_f
end

#ids_given?Boolean

Returns:

  • (Boolean)


146
147
148
# File 'lib/supernova/solr_indexer.rb', line 146

def ids_given?
  self.ids.is_a?(Array)
end

#index!Object



62
63
64
65
66
# File 'lib/supernova/solr_indexer.rb', line 62

def index!
  index_query(query_to_index) do |row|
    row_to_solr(row)
  end
end

#index_file_streamObject



178
179
180
# File 'lib/supernova/solr_indexer.rb', line 178

def index_file_stream
  @index_file_stream ||= File.open(index_file_path, "w")
end

#index_query(query) ⇒ Object



138
139
140
141
142
143
144
# File 'lib/supernova/solr_indexer.rb', line 138

def index_query(query)
  query_db(query).each do |row|
    yield(row) if block_given?
    write_to_file(row)
  end
  finish
end

#query_db(query) ⇒ Object



134
135
136
# File 'lib/supernova/solr_indexer.rb', line 134

def query_db(query)
  db.send(db.respond_to?(:query) ? :query : :select_all, query)
end

#query_to_indexObject



76
77
78
79
80
81
# File 'lib/supernova/solr_indexer.rb', line 76

def query_to_index
  raise "no table_name defined" if self.table_name.nil?
  query = "SELECT #{select_fields.join(", ")} FROM #{self.table_name}"
  query << " WHERE id IN (#{ids.join(", ")})" if ids_given?
  query
end

#row_to_solr(row) ⇒ Object



68
69
70
# File 'lib/supernova/solr_indexer.rb', line 68

def row_to_solr(row)
  row
end

#select_fieldsObject



95
96
97
# File 'lib/supernova/solr_indexer.rb', line 95

def select_fields
  default_fields + defined_fields
end

#solr_urlObject



182
183
184
# File 'lib/supernova/solr_indexer.rb', line 182

def solr_url
  Supernova::Solr.url
end

#sql_column_from_field_and_type(field, type) ⇒ Object



113
114
115
116
117
118
119
120
# File 'lib/supernova/solr_indexer.rb', line 113

def sql_column_from_field_and_type(field, type)
  return sql_date_column_from_field(field) if type == :date
  if suffix = self.class.suffix_from_type(type)
    "#{field} AS #{field}_#{suffix}"
  else
    raise "no suffix for #{type} defined"
  end
end

#sql_date_column_from_field(field) ⇒ Object



130
131
132
# File 'lib/supernova/solr_indexer.rb', line 130

def sql_date_column_from_field(field)
  %(IF(#{field} IS NULL, NULL, CONCAT(REPLACE(#{field}, " ", "T"), "Z")) AS #{field}_dt)
end

#stream_open?Boolean

Returns:

  • (Boolean)


174
175
176
# File 'lib/supernova/solr_indexer.rb', line 174

def stream_open?
  !@index_file_stream.nil?
end

#table_nameObject



72
73
74
# File 'lib/supernova/solr_indexer.rb', line 72

def table_name
  self.class.table_name || (self.class.clazz && self.class.clazz.respond_to?(:table_name) ? self.class.clazz.table_name : nil)
end

#validate_lat(lat) ⇒ Object



99
100
101
# File 'lib/supernova/solr_indexer.rb', line 99

def validate_lat(lat)
  float_or_nil_when_abs_bigger_than(lat, 90)
end

#validate_lng(lng) ⇒ Object



103
104
105
# File 'lib/supernova/solr_indexer.rb', line 103

def validate_lng(lng)
  float_or_nil_when_abs_bigger_than(lng, 180)
end

#write_to_file(to_index) ⇒ Object



154
155
156
157
158
159
160
161
162
163
164
165
# File 'lib/supernova/solr_indexer.rb', line 154

def write_to_file(to_index)
  prefix = ",\n"
  if !stream_open?
    index_file_stream.puts "{"
    prefix = nil
  end
  filtered = to_index.inject({}) do |hash, (key, value)|
    hash[key] = value if value.to_s.strip.length > 0
    hash
  end
  index_file_stream.print(%(#{prefix}"add":#{({:doc => filtered}).to_json}))
end