elasticsearch_indexed_model.rb
3.16 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
require_relative 'nested_environment'
module ElasticsearchIndexedModel
def self.included base
base.send :include, Elasticsearch::Model
base.send :include, Elasticsearch::Model::Callbacks
base.send :index_name, "#{Rails.env}_#{base.index_name}"
base.extend ClassMethods
base.send :include, InstanceMethods
base.class_eval do
settings index: { number_of_shards: 1 } do
mappings dynamic: 'false' do
base.indexed_fields.each do |field, value|
type = value[:type].presence
if type == :nested
indexes(field, type: type) do
value[:hash].each do |hash_field, hash_value|
indexes(hash_field, base.indexes_as_hash(hash_field,hash_value[:type].presence))
end
end
else
indexes(field, base.indexes_as_hash(field,type))
end
print '.'
end
end
base.__elasticsearch__.client.indices.delete \
index: base.index_name rescue nil
base.__elasticsearch__.client.indices.create \
index: base.index_name,
body: {
settings: base.settings.to_hash,
mappings: base.mappings.to_hash
}
end
end
base.send :import
end
module ClassMethods
def indexes_as_hash(name, type)
hash = {}
if type.nil?
hash[:fields] = raw_field(name, type)
else
hash[:type] = type if not type.nil?
end
hash
end
def raw_field name, type
{
raw: {
type: "string",
index: "not_analyzed"
}
}
end
def indexed_fields
fields = {
:environment => {type: :nested, hash: NestedEnvironment.environment_hash },
:created_at => {type: :date }
}
fields.update(self::SEARCHABLE_FIELDS)
fields.update(self.control_fields)
fields
end
def environment_filter environment=1
{
query: {
nested: {
path: "environment",
query: {
bool: {
must: { term: { "environment.id" => environment } },
}
}
}
}
}
end
def filter options={}
environment = options[:environment].presence
filter = {}
filter[:indices] = {:index => self.index_name, :no_match_filter => "none" }
filter[:indices][:filter] = { :bool => {} }
filter[:indices][:filter][:bool][:must] = [ environment_filter(environment) ]
filter[:indices][:filter][:bool][:should] = [ { :and => self.should_and } ] if self.respond_to? :should_and
filter
end
end
module InstanceMethods
def as_indexed_json options={}
attrs = {}
self.class.indexed_fields.each do |field, value|
type = value[:type].presence
if type == :nested
attrs[field] = {}
value[:hash].each do |hash_field, hash_value|
attrs[field][hash_field] = self.send(field).send(hash_field)
end
else
attrs[field] = self.send(field)
end
end
attrs.as_json
end
end
end