feat(subsonic): improve search2 and search3 when there are multiple words searched on. (#335)

Co-authored-by: Brian Doherty <brian@mediaserver.dohertyfamily.me>
This commit is contained in:
brian-doherty
2023-06-29 15:59:22 -05:00
committed by GitHub
parent c45c3c9041
commit cbab68b057
2 changed files with 38 additions and 21 deletions

View File

@@ -199,10 +199,13 @@ func (c *Controller) ServeSearchTwo(r *http.Request) *spec.Response {
params := r.Context().Value(CtxParams).(params.Params) params := r.Context().Value(CtxParams).(params.Params)
user := r.Context().Value(CtxUser).(*db.User) user := r.Context().Value(CtxUser).(*db.User)
query, err := params.Get("query") query, err := params.Get("query")
var queries []string
if err != nil { if err != nil {
return spec.NewError(10, "please provide a `query` parameter") return spec.NewError(10, "please provide a `query` parameter")
} }
query = fmt.Sprintf("%%%s%%", strings.Trim(query, `*"'`)) for _, s := range strings.Fields(query) {
queries = append(queries, fmt.Sprintf("%%%s%%", strings.Trim(s, `*"'`)))
}
results := &spec.SearchResultTwo{} results := &spec.SearchResultTwo{}
@@ -216,9 +219,11 @@ func (c *Controller) ServeSearchTwo(r *http.Request) *spec.Response {
} }
var artists []*db.Album var artists []*db.Album
q := c.DB. q := c.DB.Where(`parent_id IN ?`, rootQ.SubQuery())
Where(`parent_id IN ? AND (right_path LIKE ? OR right_path_u_dec LIKE ?)`, rootQ.SubQuery(), query, query). for _, s := range queries {
Preload("AlbumStar", "user_id=?", user.ID). q = q.Where(`right_path LIKE ? OR right_path_u_dec LIKE ?`, s, s)
}
q = q.Preload("AlbumStar", "user_id=?", user.ID).
Preload("AlbumRating", "user_id=?", user.ID). Preload("AlbumRating", "user_id=?", user.ID).
Offset(params.GetOrInt("artistOffset", 0)). Offset(params.GetOrInt("artistOffset", 0)).
Limit(params.GetOrInt("artistCount", 20)) Limit(params.GetOrInt("artistCount", 20))
@@ -231,9 +236,11 @@ func (c *Controller) ServeSearchTwo(r *http.Request) *spec.Response {
// search "albums" // search "albums"
var albums []*db.Album var albums []*db.Album
q = c.DB. q = c.DB.Where(`tag_artist_id IS NOT NULL`)
Where(`tag_artist_id IS NOT NULL AND (right_path LIKE ? OR right_path_u_dec LIKE ?)`, query, query). for _, s := range queries {
Preload("AlbumStar", "user_id=?", user.ID). q = q.Where(`right_path LIKE ? OR right_path_u_dec LIKE ?`, s, s)
}
q = q.Preload("AlbumStar", "user_id=?", user.ID).
Preload("AlbumRating", "user_id=?", user.ID). Preload("AlbumRating", "user_id=?", user.ID).
Offset(params.GetOrInt("albumOffset", 0)). Offset(params.GetOrInt("albumOffset", 0)).
Limit(params.GetOrInt("albumCount", 20)) Limit(params.GetOrInt("albumCount", 20))
@@ -249,10 +256,11 @@ func (c *Controller) ServeSearchTwo(r *http.Request) *spec.Response {
// search tracks // search tracks
var tracks []*db.Track var tracks []*db.Track
q = c.DB. q = c.DB.Preload("Album")
Preload("Album"). for _, s := range queries {
Where("filename LIKE ? OR filename_u_dec LIKE ?", query, query). q = q.Where(`filename LIKE ? OR filename LIKE ?`, s, s)
Preload("TrackStar", "user_id=?", user.ID). }
q = q.Preload("TrackStar", "user_id=?", user.ID).
Preload("TrackRating", "user_id=?", user.ID). Preload("TrackRating", "user_id=?", user.ID).
Offset(params.GetOrInt("songOffset", 0)). Offset(params.GetOrInt("songOffset", 0)).
Limit(params.GetOrInt("songCount", 20)) Limit(params.GetOrInt("songCount", 20))

View File

@@ -207,10 +207,13 @@ func (c *Controller) ServeSearchThree(r *http.Request) *spec.Response {
params := r.Context().Value(CtxParams).(params.Params) params := r.Context().Value(CtxParams).(params.Params)
user := r.Context().Value(CtxUser).(*db.User) user := r.Context().Value(CtxUser).(*db.User)
query, err := params.Get("query") query, err := params.Get("query")
var queries []string
if err != nil { if err != nil {
return spec.NewError(10, "please provide a `query` parameter") return spec.NewError(10, "please provide a `query` parameter")
} }
query = fmt.Sprintf("%%%s%%", strings.Trim(query, `*"'`)) for _, s := range strings.Fields(query) {
queries = append(queries, fmt.Sprintf("%%%s%%", strings.Trim(s, `*"'`)))
}
results := &spec.SearchResultThree{} results := &spec.SearchResultThree{}
@@ -218,9 +221,11 @@ func (c *Controller) ServeSearchThree(r *http.Request) *spec.Response {
var artists []*db.Artist var artists []*db.Artist
q := c.DB. q := c.DB.
Select("*, count(albums.id) album_count"). Select("*, count(albums.id) album_count").
Group("artists.id"). Group("artists.id")
Where("name LIKE ? OR name_u_dec LIKE ?", query, query). for _, s := range queries {
Joins("JOIN albums ON albums.tag_artist_id=artists.id"). q = q.Where(`name LIKE ? OR name_u_dec LIKE ?`, s, s)
}
q = q.Joins("JOIN albums ON albums.tag_artist_id=artists.id").
Preload("ArtistStar", "user_id=?", user.ID). Preload("ArtistStar", "user_id=?", user.ID).
Preload("ArtistRating", "user_id=?", user.ID). Preload("ArtistRating", "user_id=?", user.ID).
Offset(params.GetOrInt("artistOffset", 0)). Offset(params.GetOrInt("artistOffset", 0)).
@@ -241,9 +246,11 @@ func (c *Controller) ServeSearchThree(r *http.Request) *spec.Response {
Preload("TagArtist"). Preload("TagArtist").
Preload("Genres"). Preload("Genres").
Preload("AlbumStar", "user_id=?", user.ID). Preload("AlbumStar", "user_id=?", user.ID).
Preload("AlbumRating", "user_id=?", user.ID). Preload("AlbumRating", "user_id=?", user.ID)
Where("tag_title LIKE ? OR tag_title_u_dec LIKE ?", query, query). for _, s := range queries {
Offset(params.GetOrInt("albumOffset", 0)). q = q.Where(`tag_title LIKE ? OR tag_title_u_dec LIKE ?`, s, s)
}
q = q.Offset(params.GetOrInt("albumOffset", 0)).
Limit(params.GetOrInt("albumCount", 20)) Limit(params.GetOrInt("albumCount", 20))
if m := getMusicFolder(c.MusicPaths, params); m != "" { if m := getMusicFolder(c.MusicPaths, params); m != "" {
q = q.Where("root_dir=?", m) q = q.Where("root_dir=?", m)
@@ -262,9 +269,11 @@ func (c *Controller) ServeSearchThree(r *http.Request) *spec.Response {
Preload("Album.TagArtist"). Preload("Album.TagArtist").
Preload("Genres"). Preload("Genres").
Preload("TrackStar", "user_id=?", user.ID). Preload("TrackStar", "user_id=?", user.ID).
Preload("TrackRating", "user_id=?", user.ID). Preload("TrackRating", "user_id=?", user.ID)
Where("tag_title LIKE ? OR tag_title_u_dec LIKE ?", query, query). for _, s := range queries {
Offset(params.GetOrInt("songOffset", 0)). q = q.Where(`tag_title LIKE ? OR tag_title_u_dec LIKE ?`, s, s)
}
q = q.Offset(params.GetOrInt("songOffset", 0)).
Limit(params.GetOrInt("songCount", 20)) Limit(params.GetOrInt("songCount", 20))
if m := getMusicFolder(c.MusicPaths, params); m != "" { if m := getMusicFolder(c.MusicPaths, params); m != "" {
q = q. q = q.