# Search Integration Design: Location Features ## 1. Search Index Integration ### Schema Modifications ```python from django.contrib.postgres.indexes import GinIndex from django.contrib.postgres.search import SearchVectorField class SearchIndex(models.Model): # Existing fields content = SearchVectorField() # New location fields location_point = gis_models.PointField(srid=4326, null=True) location_geohash = models.CharField(max_length=12, null=True, db_index=True) location_metadata = models.JSONField( default=dict, help_text="Address, city, state for text search" ) class Meta: indexes = [ GinIndex(fields=['content']), models.Index(fields=['location_geohash']), ] ``` ### Indexing Strategy 1. **Spatial Indexing**: - Use PostGIS GiST index on `location_point` - Add Geohash index for fast proximity searches 2. **Text Integration**: ```python SearchIndex.objects.update( content=SearchVector('content') + SearchVector('location_metadata__city', weight='B') + SearchVector('location_metadata__state', weight='C') ) ``` 3. **Update Triggers**: - Signal handlers on ParkLocation/RideLocation changes - Daily reindexing task for data consistency ## 2. "Near Me" Functionality ### Query Architecture ```mermaid sequenceDiagram participant User participant Frontend participant Geocoder participant SearchService User->>Frontend: Clicks "Near Me" Frontend->>Browser: Get geolocation Browser->>Frontend: Coordinates (lat, lng) Frontend->>Geocoder: Reverse geocode Geocoder->>Frontend: Location context Frontend->>SearchService: { query, location, radius } SearchService->>Database: Spatial search Database->>SearchService: Ranked results SearchService->>Frontend: Results with distances ``` ### Ranking Algorithm ```python def proximity_score(point, user_point, max_distance=100000): """Calculate proximity score (0-1)""" distance = point.distance(user_point) return max(0, 1 - (distance / max_distance)) def combined_relevance(text_score, proximity_score, weights=[0.7, 0.3]): return (text_score * weights[0]) + (proximity_score * weights[1]) ``` ### Geocoding Integration - Use Nominatim for address → coordinate conversion - Cache results for 30 days - Fallback to IP-based location estimation ## 3. Search Filters ### Filter Types | Filter | Parameters | Example | |--------|------------|---------| | `radius` | `lat, lng, km` | `?radius=40.123,-75.456,50` | | `bounds` | `sw_lat,sw_lng,ne_lat,ne_lng` | `?bounds=39.8,-77.0,40.2,-75.0` | | `region` | `state/country` | `?region=Ohio` | | `highway` | `exit_number` | `?highway=Exit 42` | ### Implementation ```python class LocationFilter(SearchFilter): def apply(self, queryset, request): if 'radius' in request.GET: point, radius = parse_radius(request.GET['radius']) queryset = queryset.filter( location_point__dwithin=(point, Distance(km=radius)) if 'bounds' in request.GET: polygon = parse_bounding_box(request.GET['bounds']) queryset = queryset.filter(location_point__within=polygon) return queryset ``` ## 4. Performance Optimization ### Strategies 1. **Hybrid Indexing**: - GiST index for spatial queries - Geohash for quick distance approximations 2. **Query Optimization**: ```sql EXPLAIN ANALYZE SELECT * FROM search_index WHERE ST_DWithin(location_point, ST_MakePoint(-75.456,40.123), 0.1); ``` 3. **Caching Layers**: ```mermaid graph LR A[Request] --> B{Geohash Tile?} B -->|Yes| C[Redis Cache] B -->|No| D[Database Query] D --> E[Cache Results] E --> F[Response] C --> F ``` 4. **Rate Limiting**: - 10 location searches/minute per user - Tiered limits for authenticated users ## 5. Frontend Integration ### UI Components 1. **Location Autocomplete**: ```javascript setFilters({...filters, location: result})} /> ``` 2. **Proximity Toggle**: ```jsx { if (enabled) navigator.geolocation.getCurrentPosition(...) }} /> ``` 3. **Result Distance Indicators**: ```jsx

{item.name}

``` ### Map Integration ```javascript function updateMapResults(results) { results.forEach(item => { if (item.type === 'park') { createParkMarker(item); } else if (item.type === 'cluster') { createClusterMarker(item); } }); } ``` ## Rollout Plan 1. **Phase 1**: Index integration (2 weeks) 2. **Phase 2**: Backend implementation (3 weeks) 3. **Phase 3**: Frontend components (2 weeks) 4. **Phase 4**: Beta testing (1 week) 5. **Phase 5**: Full rollout ## Metrics & Monitoring - Query latency percentiles - Cache hit rate - Accuracy of location results - Adoption rate of location filters