record_data.rb
2.98 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
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
module Searchkick
class RecordData
TYPE_KEYS = ["type", :type]
attr_reader :index, :record
def initialize(index, record)
@index = index
@record = record
end
def index_data
data = record_data
data[:data] = search_data
{index: data}
end
def update_data(method_name)
data = record_data
data[:data] = {doc: search_data(method_name)}
{update: data}
end
def delete_data
{delete: record_data}
end
def search_id
id = record.respond_to?(:search_document_id) ? record.search_document_id : record.id
id.is_a?(Numeric) ? id : id.to_s
end
def document_type(ignore_type = false)
index.klass_document_type(record.class, ignore_type)
end
def record_data
data = {
_index: index.name,
_id: search_id
}
data[:routing] = record.search_routing if record.respond_to?(:search_routing)
data
end
private
def search_data(method_name = nil)
partial_reindex = !method_name.nil?
source = record.send(method_name || :search_data)
# conversions
index.conversions_fields.each do |conversions_field|
if source[conversions_field]
source[conversions_field] = source[conversions_field].map { |k, v| {query: k, count: v} }
end
end
# hack to prevent generator field doesn't exist error
if !partial_reindex
index.suggest_fields.each do |field|
if !source.key?(field) && !source.key?(field.to_sym)
source[field] = nil
end
end
end
# locations
index.locations_fields.each do |field|
if source[field]
if !source[field].is_a?(Hash) && (source[field].first.is_a?(Array) || source[field].first.is_a?(Hash))
# multiple locations
source[field] = source[field].map { |a| location_value(a) }
else
source[field] = location_value(source[field])
end
end
end
if index.options[:inheritance]
if !TYPE_KEYS.any? { |tk| source.key?(tk) }
source[:type] = document_type(true)
end
end
cast_big_decimal(source)
source
end
def location_value(value)
if value.is_a?(Array)
value.map(&:to_f).reverse
elsif value.is_a?(Hash)
{lat: value[:lat].to_f, lon: value[:lon].to_f}
else
value
end
end
# change all BigDecimal values to floats due to
# https://github.com/rails/rails/issues/6033
# possible loss of precision :/
def cast_big_decimal(obj)
case obj
when BigDecimal
obj.to_f
when Hash
obj.each do |k, v|
# performance
if v.is_a?(BigDecimal)
obj[k] = v.to_f
elsif v.is_a?(Enumerable)
obj[k] = cast_big_decimal(v)
end
end
when Enumerable
obj.map do |v|
cast_big_decimal(v)
end
else
obj
end
end
end
end