@@ -92,13 +92,12 @@ def __init__(self, using='default', index=None, doc_type=None, extra=None):
9292 self ._doc_type = []
9393 self ._doc_type_map = {}
9494 if isinstance (doc_type , (tuple , list )):
95- for dt in doc_type :
96- self ._add_doc_type (dt )
95+ self ._doc_type .extend (doc_type )
9796 elif isinstance (doc_type , collections .Mapping ):
9897 self ._doc_type .extend (doc_type .keys ())
9998 self ._doc_type_map .update (doc_type )
10099 elif doc_type :
101- self ._add_doc_type (doc_type )
100+ self ._doc_type . append (doc_type )
102101
103102 self ._params = {}
104103 self ._extra = extra or {}
@@ -159,11 +158,52 @@ def index(self, *index):
159158
160159 return s
161160
162- def _add_doc_type (self , doc_type ):
163- if hasattr (doc_type , '_doc_type' ):
164- self ._doc_type_map [doc_type ._doc_type .name ] = doc_type
165- doc_type = doc_type ._doc_type .name
166- self ._doc_type .append (doc_type )
161+ def _get_doc_type (self ):
162+ """
163+ Return a list of doc_type names to be used
164+ """
165+ return list (set (dt ._doc_type .name if hasattr (dt , '_doc_type' ) else dt for dt in self ._doc_type ))
166+
167+ def _resolve_nested (self , field , parent_class = None ):
168+ doc_class = Hit
169+ if hasattr (parent_class , '_doc_type' ):
170+ nested_field = parent_class ._doc_type .resolve_field (field )
171+
172+ else :
173+ for dt in self ._doc_type :
174+ if not hasattr (dt , '_doc_type' ):
175+ continue
176+ nested_field = dt ._doc_type .resolve_field (field )
177+ if nested_field is not None :
178+ break
179+
180+ if nested_field is not None :
181+ return nested_field ._doc_class
182+
183+ return doc_class
184+
185+ def _get_result (self , hit , parent_class = None ):
186+ doc_class = Hit
187+ dt = hit .get ('_type' )
188+
189+ if '_nested' in hit :
190+ doc_class = self ._resolve_nested (hit ['_nested' ]['field' ], parent_class )
191+
192+ elif dt in self ._doc_type_map :
193+ doc_class = self ._doc_type_map [dt ]
194+
195+ else :
196+ for doc_type in self ._doc_type :
197+ if hasattr (doc_type , '_doc_type' ) and doc_type ._doc_type .matches (hit ):
198+ doc_class = doc_type
199+ break
200+
201+ for t in hit .get ('inner_hits' , ()):
202+ hit ['inner_hits' ][t ] = Response (self , hit ['inner_hits' ][t ], doc_class = doc_class )
203+
204+ callback = getattr (doc_class , 'from_es' , doc_class )
205+ return callback (hit )
206+
167207
168208 def doc_type (self , * doc_type , ** kwargs ):
169209 """
@@ -186,8 +226,7 @@ def doc_type(self, *doc_type, **kwargs):
186226 s ._doc_type = []
187227 s ._doc_type_map = {}
188228 else :
189- for dt in doc_type :
190- s ._add_doc_type (dt )
229+ s ._doc_type .extend (doc_type )
191230 s ._doc_type .extend (kwargs .keys ())
192231 s ._doc_type_map .update (kwargs )
193232 return s
@@ -528,6 +567,7 @@ def highlight(self, *fields, **kwargs):
528567 Search().highlight('title', fragment_size=50).highlight('body', fragment_size=100)
529568
530569 which will produce::
570+
531571 {
532572 "highlight": {
533573 "fields": {
@@ -615,7 +655,7 @@ def count(self):
615655 # TODO: failed shards detection
616656 return es .count (
617657 index = self ._index ,
618- doc_type = self ._doc_type ,
658+ doc_type = self ._get_doc_type () ,
619659 body = d ,
620660 ** self ._params
621661 )['count' ]
@@ -634,7 +674,7 @@ def execute(self, ignore_cache=False):
634674 self ,
635675 es .search (
636676 index = self ._index ,
637- doc_type = self ._doc_type ,
677+ doc_type = self ._get_doc_type () ,
638678 body = self .to_dict (),
639679 ** self ._params
640680 )
@@ -657,12 +697,10 @@ def scan(self):
657697 es ,
658698 query = self .to_dict (),
659699 index = self ._index ,
660- doc_type = self ._doc_type ,
700+ doc_type = self ._get_doc_type () ,
661701 ** self ._params
662702 ):
663- callback = self ._doc_type_map .get (hit ['_type' ], Hit )
664- callback = getattr (callback , 'from_es' , callback )
665- yield callback (hit )
703+ yield self ._get_result (hit )
666704
667705 def delete (self ):
668706 """
@@ -675,7 +713,7 @@ def delete(self):
675713 es .delete_by_query (
676714 index = self ._index ,
677715 body = self .to_dict (),
678- doc_type = self ._doc_type ,
716+ doc_type = self ._get_doc_type () ,
679717 ** self ._params
680718 )
681719 )
@@ -720,7 +758,7 @@ def to_dict(self):
720758 if s ._index :
721759 meta ['index' ] = s ._index
722760 if s ._doc_type :
723- meta ['type' ] = s ._doc_type
761+ meta ['type' ] = s ._get_doc_type ()
724762 meta .update (s ._params )
725763
726764 out .append (meta )
@@ -737,7 +775,7 @@ def execute(self, ignore_cache=False, raise_on_error=True):
737775
738776 responses = es .msearch (
739777 index = self ._index ,
740- doc_type = self ._doc_type ,
778+ doc_type = self ._get_doc_type () ,
741779 body = self .to_dict (),
742780 ** self ._params
743781 )
0 commit comments