feat(search): add phonetic/fuzzy search via pg_trgm
This commit is contained in:
parent
eb2f7e0d8c
commit
d4f1d08518
1 changed files with 20 additions and 7 deletions
|
|
@ -52,13 +52,25 @@ func NewTrackSearchServiceWithDB(db *database.Database) *TrackSearchService {
|
|||
func (s *TrackSearchService) SearchTracks(ctx context.Context, params TrackSearchParams) ([]*models.Track, int64, error) {
|
||||
query := s.db.Model(&models.Track{}).Where("is_public = ? AND deleted_at IS NULL", true)
|
||||
|
||||
// Full-text search on title, artist, album
|
||||
// Full-text search on title, artist, album (v0.203 Lot K: pg_trgm similarity, fallback ILIKE for SQLite)
|
||||
if params.Query != "" {
|
||||
searchTerm := "%" + strings.ToLower(params.Query) + "%"
|
||||
query = query.Where(
|
||||
"LOWER(title) LIKE ? OR LOWER(artist) LIKE ? OR LOWER(album) LIKE ?",
|
||||
searchTerm, searchTerm, searchTerm,
|
||||
)
|
||||
q := strings.ToLower(strings.TrimSpace(params.Query))
|
||||
if q != "" {
|
||||
searchTerm := "%" + q + "%"
|
||||
if s.db.Dialector.Name() == "sqlite" {
|
||||
// SQLite: use LIKE (no pg_trgm)
|
||||
query = query.Where(
|
||||
"LOWER(title) LIKE ? OR LOWER(artist) LIKE ? OR LOWER(album) LIKE ?",
|
||||
searchTerm, searchTerm, searchTerm,
|
||||
)
|
||||
} else {
|
||||
// PostgreSQL: pg_trgm similarity for fuzzy match
|
||||
query = query.Where(
|
||||
`(similarity(LOWER(title), ?) > 0.1 OR similarity(LOWER(artist), ?) > 0.1 OR similarity(LOWER(album), ?) > 0.1)`,
|
||||
q, q, q,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Tag search (tracks.tags pq.StringArray, migration 085)
|
||||
|
|
@ -142,7 +154,8 @@ func (s *TrackSearchService) SearchTracks(ctx context.Context, params TrackSearc
|
|||
// Handle different sorting options
|
||||
switch sortBy {
|
||||
case "relevance":
|
||||
// Fallback: order by play_count when no full-text rank available
|
||||
// When query is set, similarity() in WHERE already filters; order by play_count as proxy for relevance
|
||||
// (GORM Order doesn't support placeholders for similarity-based sort)
|
||||
query = query.Order("play_count DESC")
|
||||
case "popularity":
|
||||
// Sort by like_count (popularity)
|
||||
|
|
|
|||
Loading…
Reference in a new issue