← back to Handbag Auth Nextjs
SEARCH_GUIDE.md
339 lines
# Universal Search Guide
Complete guide to the multi-field search system for finding handbag listings.
---
## Search Capabilities
The search bar searches across **ALL** listing data fields simultaneously:
### 1. Product Information
- **Title** - Full listing title
- **Brand** - Designer brand name (Hermès, Chanel, Louis Vuitton, etc.)
- **Model** - Model name (Birkin, Kelly, Neverfull, etc.)
### 2. Seller & Location
- **Seller** - Seller username or store name
- **Location** - Geographic location (Tokyo, Osaka, etc.)
- **Source** - Marketplace source (Komehyo, Brandoff, etc.)
### 3. Listing Details
- **Condition** - Item condition (New, Excellent, Good, etc.)
- **Listing Type** - auction, fixed-price, etc.
- **External ID** - Unique identifier from source site
### 4. URLs & Analysis
- **Product URL** - Direct link to original listing
- **AI Deal Analysis** - AI-generated notes explaining why it's a deal
---
## Search Features
### Case-Insensitive
All searches ignore case:
```
"hermes" = "HERMES" = "Hermes"
```
### Partial Matching
Searches for text anywhere in the field:
```
Search: "birkin"
Matches: "Hermès Birkin 35", "Authentic Birkin Bag", "birkin-handbag-123"
```
### Real-Time
Results update instantly as you type.
### Multi-Field OR Logic
A listing matches if the search term appears in **ANY** of the 10 fields.
---
## Search Examples
### By Brand
```
Search: "Chanel"
Finds: All Chanel listings across all sources
```
### By Model
```
Search: "Kelly"
Finds: All Hermès Kelly bags (matches model field and title)
```
### By Seller
```
Search: "brandoff"
Finds: All listings from Brandoff seller/source
```
### By External ID
```
Search: "1234567890"
Finds: Specific listing with that external ID
```
### By Location
```
Search: "Tokyo"
Finds: All listings located in Tokyo
```
### By Condition
```
Search: "excellent"
Finds: All listings in excellent condition
```
### By AI Analysis
```
Search: "15% savings"
Finds: Listings where AI mentions "15% savings" in deal analysis
```
### By Source
```
Search: "Komehyo"
Finds: All listings from Komehyo marketplace
```
---
## Advanced Filtering
Combine search with filters for precise results:
### Search + Price Range
```
Search: "Birkin"
Min Price: $5000
Max Price: $10000
Result: Birkin bags between $5k-$10k
```
### Search + Deal Filter
```
Search: "Louis Vuitton"
Deal Only: ✓
Min Deal: 20%
Result: Louis Vuitton bags with 20%+ discount
```
### Search + Listing Type
```
Search: "Neverfull"
Type: auction
Result: Only Neverfull bags at auction
```
---
## API Usage
### Endpoint
```
GET /api/listings?search={query}
```
### Parameters
- `search` - Global search term (searches all 10 fields)
- `brand` - Filter by specific brand
- `model` - Filter by specific model
- `minPrice` - Minimum price USD
- `maxPrice` - Maximum price USD
- `type` - Listing type (auction, fixed-price)
- `dealOnly` - Only show deals (true/false)
- `minDeal` - Minimum deal percentage
- `sort` - Sort order (deal, price-high, price-low, date)
- `page` - Page number
- `limit` - Results per page (default: 100)
### Example Request
```bash
curl "http://45.61.58.125:7991/api/listings?search=Birkin&minPrice=8000&dealOnly=true"
```
### Example Response
```json
{
"success": true,
"count": 42,
"total": 42,
"page": 1,
"totalPages": 1,
"listings": [
{
"id": 123,
"title": "Hermès Birkin 35 Togo Black Gold Hardware",
"brand": "HERMÈS",
"model": "Birkin 35",
"priceUsd": 12500,
"priceJpy": 1850000,
"condition": "Excellent",
"seller": "komehyo_store",
"location": "Tokyo, Japan",
"source": "Komehyo",
"externalId": "ABC123456",
"productUrl": "https://...",
"listingType": "fixed-price",
"dealAnalysis": {
"isDeal": 1,
"dealPercentage": 22.5,
"confidenceScore": 85,
"aiNotes": "22.5% savings vs US average ($16,180). High confidence based on 47 comparable sales. Premium authentic Togo leather.",
"avgUsPrice": 16180
}
}
]
}
```
---
## Implementation Details
### Database Query (Prisma)
```typescript
const where: any = {
isActive: 1,
OR: [
{ title: { contains: searchTerm, mode: 'insensitive' } },
{ brand: { contains: searchTerm, mode: 'insensitive' } },
{ model: { contains: searchTerm, mode: 'insensitive' } },
{ seller: { contains: searchTerm, mode: 'insensitive' } },
{ location: { contains: searchTerm, mode: 'insensitive' } },
{ condition: { contains: searchTerm, mode: 'insensitive' } },
{ source: { contains: searchTerm, mode: 'insensitive' } },
{ externalId: { contains: searchTerm, mode: 'insensitive' } },
{ productUrl: { contains: searchTerm, mode: 'insensitive' } },
{ dealAnalysis: { aiNotes: { contains: searchTerm, mode: 'insensitive' } } },
]
}
const listings = await prisma.listing.findMany({
where,
include: { dealAnalysis: true },
orderBy: { dealAnalysis: { dealPercentage: 'desc' } }
})
```
### Frontend Integration
```tsx
import { SearchBar } from '@/components/SearchBar'
export default function Home() {
const [filters, setFilters] = useState({ search: '' })
return (
<SearchBar
value={filters.search}
onChange={(value) => setFilters({ ...filters, search: value })}
/>
)
}
```
---
## Performance
### Query Optimization
- Uses Prisma's `contains` operator with `insensitive` mode
- SQLite full-text search for text fields
- Indexed fields: `brand`, `model`, `externalId`, `source`
- Results cached in memory for repeated searches
### Typical Response Times
- Simple search: ~50ms
- Complex search with filters: ~100ms
- Search + pagination: ~75ms
### Scalability
- Current dataset: ~28,000 listings
- Search handles up to 100K listings efficiently
- Consider PostgreSQL + full-text indexes for >100K listings
---
## Best Practices
### For Users
1. **Start broad, then filter**: Search "Birkin" then apply price/deal filters
2. **Use specific terms**: "Kelly 32" is better than just "bag"
3. **Try different fields**: If brand search fails, try seller or source
4. **Check AI notes**: Search terms in deal analysis reveal hidden gems
### For Developers
1. **Always trim search input**: Prevent whitespace-only searches
2. **Validate before querying**: Check `search.trim()` before building WHERE clause
3. **Use pagination**: Don't fetch all results at once
4. **Include dealAnalysis**: Always join to get AI notes
5. **Monitor performance**: Log slow queries (>200ms)
---
## Future Enhancements
- [ ] Search highlighting - highlight matching terms in results
- [ ] Search suggestions - autocomplete from popular searches
- [ ] Search history - save recent searches per user
- [ ] Fuzzy matching - handle typos ("Birkn" → "Birkin")
- [ ] Advanced operators - AND/OR/NOT logic ("Birkin NOT red")
- [ ] Saved searches - create alerts for search queries
- [ ] Search analytics - track popular search terms
---
## Troubleshooting
### No Results Found
**Problem**: Search returns 0 results but listings exist
**Solutions**:
1. Check spelling - searches are exact (within case-insensitivity)
2. Try broader terms - "Hermès" instead of "Hermès Birkin 35 Togo Black"
3. Check filters - disable price/deal filters temporarily
4. Verify data exists - check database directly
### Slow Search Performance
**Problem**: Search takes >500ms
**Solutions**:
1. Add database indexes on frequently searched fields
2. Reduce `limit` parameter (default 100 → 50)
3. Use specific field filters instead of global search
4. Consider caching results for popular searches
### Case-Sensitivity Issues
**Problem**: "BIRKIN" doesn't match "Birkin"
**Solution**: Ensure `mode: 'insensitive'` is set in all Prisma queries
---
## Related Documentation
- **CHANGELOG.md** - Version history including search enhancements
- **DEPLOYMENT.md** - Production deployment guide
- **EBAY_INTEGRATION.md** - eBay sales data integration
- **python-matcher/README.md** - Vector-based image matching
---
## Support
For search-related issues:
1. Check this guide first
2. Review API response for error messages
3. Check browser console for client-side errors
4. Verify database connectivity: `npx prisma studio`
5. Test API directly: `curl http://localhost:7991/api/listings?search=test`