mirror of
https://github.com/pacnpal/thrillwiki_django_no_react.git
synced 2025-12-20 09:51:09 -05:00
major changes, including tailwind v4
This commit is contained in:
190
memory-bank/documentation/search_integration_design.md
Normal file
190
memory-bank/documentation/search_integration_design.md
Normal file
@@ -0,0 +1,190 @@
|
||||
# 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
|
||||
<LocationSearch
|
||||
onSelect={(result) => setFilters({...filters, location: result})}
|
||||
/>
|
||||
```
|
||||
|
||||
2. **Proximity Toggle**:
|
||||
```jsx
|
||||
<Toggle
|
||||
label="Near Me"
|
||||
onChange={(enabled) => {
|
||||
if (enabled) navigator.geolocation.getCurrentPosition(...)
|
||||
}}
|
||||
/>
|
||||
```
|
||||
|
||||
3. **Result Distance Indicators**:
|
||||
```jsx
|
||||
<SearchResult>
|
||||
<h3>{item.name}</h3>
|
||||
<DistanceBadge km={item.distance} />
|
||||
</SearchResult>
|
||||
```
|
||||
|
||||
### 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
|
||||
Reference in New Issue
Block a user