Skip to content

Commit 11df40b

Browse files
committed
refactoring index to model map concern into Registry to address elastic#838 and improve autoloader compatibility
1 parent 81536dd commit 11df40b

File tree

2 files changed

+51
-10
lines changed

2 files changed

+51
-10
lines changed

elasticsearch-model/lib/elasticsearch/model/adapters/multiple.rb

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -107,16 +107,14 @@ def __ids_by_type
107107
#
108108
def __type_for_hit(hit)
109109

110-
key = "#{hit[:_index]}::#{hit[:_type]}" if hit[:_type] && hit[:_type] != '_doc'
111-
key = hit[:_index] unless key
112-
113-
# DVB -- not sure the ramifications of this - but do not memoize the model/klass
114-
# I do not think that caching the types is necessary, minimal processing savings
115-
# at the expense of broken STI autoloading in development, see #848
116-
Registry.all.detect do |model|
117-
(model.index_name == hit[:_index] && __no_type?(hit)) ||
118-
(model.index_name == hit[:_index] && model.document_type == hit[:_type])
110+
key = if hit[:_type] && hit[:_type] != '_doc'
111+
"#{hit[:_index]}::#{hit[:_type]}"
112+
else
113+
hit[:_index]
119114
end
115+
116+
# DVB -- #838, refactor the lookup of index name to model into the Registry
117+
Registry.lookup(key, hit[:_type])
120118
end
121119

122120
def __no_type?(hit)

elasticsearch-model/lib/elasticsearch/model/multimodel.rb

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,11 @@ module Elasticsearch
1919
module Model
2020

2121
# Keeps a global registry of classes that include `Elasticsearch::Model`
22-
#
22+
# Keeps a global registry of index to class mappings
2323
class Registry
2424
def initialize
2525
@models = []
26+
@indexes = {}
2627
end
2728

2829
# Returns the unique instance of the registry (Singleton)
@@ -45,22 +46,64 @@ def self.all
4546
__instance.models
4647
end
4748

49+
def self.indexes
50+
__instance.indexes
51+
end
52+
53+
def self.add_index(index, model)
54+
__instance.add_index(index, model)
55+
end
56+
4857
# Adds a model to the registry
4958
#
5059
def add(klass)
5160
# Detect already loaded models and ensure that a duplicate is not stored
5261
if i = @models.index{ |_class| _class.name == klass.name }
5362
@models[i] = klass
63+
# clear the cached index map (autoloading in development causes this)
64+
@indexes.clear
5465
else
5566
@models << klass
5667
end
5768
end
5869

70+
def add_index(index, model)
71+
@indexes[index] = model
72+
end
73+
5974
# Returns a copy of the registered models
6075
#
6176
def models
6277
@models.dup
6378
end
79+
80+
def indexes
81+
@indexes.dup
82+
end
83+
84+
##
85+
# Find the model matching the given index and document type from a search hit
86+
# Cache the index->model mapping for performance
87+
# Clear the index cache when models are reloaded
88+
def self.lookup(index, type=nil)
89+
if Registry.indexes.has_key?(index)
90+
# Cache hit
91+
Registry.indexes[index]
92+
else
93+
# Cache bust
94+
model = if type.nil? or type == "_doc"
95+
# lookup strictly by index for generic document types
96+
Registry.all.detect{|m| m.index_name == index}
97+
else
98+
# lookup using index and type
99+
Registry.all.detect{|m| m.index_name == index and model.document_type == type}
100+
end
101+
# cache the index to model mapping
102+
Registry.add_index(index, model)
103+
model
104+
end
105+
end
106+
64107
end
65108

66109
# Wraps a collection of models when querying multiple indices

0 commit comments

Comments
 (0)