@@ -722,25 +722,33 @@ def view_search(self, q, args):
722722 radius = float (radius )
723723 except Exception :
724724 abort_validation ("Spatial parameters must be numeric." )
725- # Join BaseStudy -> Study -> Analysis -> Point
726- q = q .join (Study , Study .base_study_id == self ._model .id )
727- q = q .join (Analysis , Analysis .study_id == Study .id )
728- q = q .join (Point , Point .analysis_id == Analysis .id )
729- # Box filter first, then Euclidean distance
730- q = q .filter (
731- Point .x <= x + radius ,
732- Point .x >= x - radius ,
733- Point .y <= y + radius ,
734- Point .y >= y - radius ,
735- Point .z <= z + radius ,
736- Point .z >= z - radius ,
737- (Point .x - x ) * (Point .x - x )
738- + (Point .y - y ) * (Point .y - y )
739- + (Point .z - z ) * (Point .z - z )
740- <= radius * radius ,
725+ # Use EXISTS so we do not duplicate base studies when filtering by spatial criteria
726+ spatial_point = aliased (Point )
727+ spatial_analysis = aliased (Analysis )
728+ spatial_study = aliased (Study )
729+
730+ spatial_filter = (
731+ sa .select (sa .literal (True ))
732+ .select_from (spatial_study )
733+ .join (spatial_analysis , spatial_analysis .study_id == spatial_study .id )
734+ .join (spatial_point , spatial_point .analysis_id == spatial_analysis .id )
735+ .where (
736+ spatial_study .base_study_id == self ._model .id ,
737+ spatial_point .x <= x + radius ,
738+ spatial_point .x >= x - radius ,
739+ spatial_point .y <= y + radius ,
740+ spatial_point .y >= y - radius ,
741+ spatial_point .z <= z + radius ,
742+ spatial_point .z >= z - radius ,
743+ (spatial_point .x - x ) * (spatial_point .x - x )
744+ + (spatial_point .y - y ) * (spatial_point .y - y )
745+ + (spatial_point .z - z ) * (spatial_point .z - z )
746+ <= radius * radius ,
747+ )
748+ .correlate (self ._model )
749+ .exists ()
741750 )
742- # Only return distinct base studies
743- q = q .distinct ()
751+ q = q .filter (spatial_filter )
744752 elif any (v is not None for v in [x , y , z , radius ]):
745753 abort_validation ("Spatial query requires x, y, z, and radius together." )
746754
0 commit comments