diff --git a/elasticsearch-model/lib/elasticsearch/model/adapters/multiple.rb b/elasticsearch-model/lib/elasticsearch/model/adapters/multiple.rb
index 30d851043..7e91b6962 100644
--- a/elasticsearch-model/lib/elasticsearch/model/adapters/multiple.rb
+++ b/elasticsearch-model/lib/elasticsearch/model/adapters/multiple.rb
@@ -106,17 +106,15 @@ def __ids_by_type
           # @api private
           #
           def __type_for_hit(hit)
-            @@__types ||= {}
 
-            key = "#{hit[:_index]}::#{hit[:_type]}" if hit[:_type] && hit[:_type] != '_doc'
-            key = hit[:_index] unless key
-
-            @@__types[key] ||= begin
-              Registry.all.detect do |model|
-                (model.index_name == hit[:_index] && __no_type?(hit)) ||
-                    (model.index_name == hit[:_index] && model.document_type == hit[:_type])
-              end
+            key = if hit[:_type] && hit[:_type] != '_doc'
+              "#{hit[:_index]}::#{hit[:_type]}"
+            else
+              hit[:_index]
             end
+
+            # DVB -- #838, refactor the lookup of index name to model into the Registry
+            Registry.lookup(key, hit[:_type])
           end
 
           def __no_type?(hit)
diff --git a/elasticsearch-model/lib/elasticsearch/model/multimodel.rb b/elasticsearch-model/lib/elasticsearch/model/multimodel.rb
index 6b5fc2a81..d71c44552 100644
--- a/elasticsearch-model/lib/elasticsearch/model/multimodel.rb
+++ b/elasticsearch-model/lib/elasticsearch/model/multimodel.rb
@@ -19,10 +19,11 @@ module Elasticsearch
   module Model
 
     # Keeps a global registry of classes that include `Elasticsearch::Model`
-    #
+    # Keeps a global registry of index to class mappings
     class Registry
       def initialize
         @models = []
+        @indexes = {}
       end
 
       # Returns the unique instance of the registry (Singleton)
@@ -45,10 +46,29 @@ def self.all
         __instance.models
       end
 
+      def self.indexes
+        __instance.indexes
+      end
+
+      def self.add_index(index, model)
+        __instance.add_index(index, model)
+      end
+
       # Adds a model to the registry
       #
       def add(klass)
-        @models << klass
+        # Detect already loaded models and ensure that a duplicate is not stored
+        if i = @models.index{ |_class| _class.name == klass.name }
+          @models[i] = klass
+          # clear the cached index map (autoloading in development causes this)
+          @indexes.clear
+        else
+          @models << klass
+        end
+      end
+
+      def add_index(index, model)
+        @indexes[index] = model
       end
 
       # Returns a copy of the registered models
@@ -56,6 +76,34 @@ def add(klass)
       def models
         @models.dup
       end
+
+      def indexes
+        @indexes.dup
+      end
+
+      ##
+      # Find the model matching the given index and document type from a search hit
+      # Cache the index->model mapping for performance
+      # Clear the index cache when models are reloaded
+      def self.lookup(index, type=nil)
+        if Registry.indexes.has_key?(index)
+          # Cache hit
+          Registry.indexes[index]
+        else
+          # Cache bust
+          model = if type.nil? or type == "_doc"
+            # lookup strictly by index for generic document types
+            Registry.all.detect{|m| m.index_name == index}
+          else
+            # lookup using index and type
+            Registry.all.detect{|m| m.index_name == index and model.document_type == type}
+          end
+          # cache the index to model mapping
+          Registry.add_index(index, model)
+          model
+        end
+      end
+
     end
 
     # Wraps a collection of models when querying multiple indices