Search: Detect and set filters based on search terms

Reduces the amount of typing necessary to search for faces, videos,
favorites, stacks, panoramas, scans, and monochrome pictures.
This commit is contained in:
Michael Mayer 2021-09-03 20:14:11 +02:00
parent 2bde7e5696
commit 9ba396e50f
5 changed files with 80 additions and 2 deletions

View file

@ -51,8 +51,23 @@ func Geo(f form.GeoSearch) (results GeoResults, err error) {
}
}
// Set search filters based on search terms.
if terms := txt.SearchTerms(f.Query); len(terms) > 0 {
switch {
case terms["faces"]:
f.Query = strings.ReplaceAll(f.Query, "faces", "")
f.Faces = "true"
case terms["videos"]:
f.Query = strings.ReplaceAll(f.Query, "videos", "")
f.Video = true
case terms["favorites"]:
f.Query = strings.ReplaceAll(f.Query, "favorites", "")
f.Favorite = true
}
}
// Filter by label, label category and keywords.
if f.Query != "" {
// Filter by label, label category and keywords.
var categories []entity.Category
var labels []entity.Label
var labelIds []uint

View file

@ -86,8 +86,11 @@ func TestGeo(t *testing.T) {
t.Fatal(err)
}
assert.LessOrEqual(t, 1, len(result))
assert.Equal(t, "1000017", result[0].ID)
assert.IsType(t, GeoResults{}, result)
if len(result) > 0 {
assert.Equal(t, "1000017", result[0].ID)
}
})
t.Run("search for review false, quality > 0", func(t *testing.T) {

View file

@ -144,6 +144,33 @@ func PhotoSearch(f form.PhotoSearch) (results PhotoResults, count int, err error
}
}
// Set search filters based on search terms.
if terms := txt.SearchTerms(f.Query); len(terms) > 0 {
switch {
case terms["faces"]:
f.Query = strings.ReplaceAll(f.Query, "faces", "")
f.Faces = "true"
case terms["videos"]:
f.Query = strings.ReplaceAll(f.Query, "videos", "")
f.Video = true
case terms["favorites"]:
f.Query = strings.ReplaceAll(f.Query, "favorites", "")
f.Favorite = true
case terms["stacks"]:
f.Query = strings.ReplaceAll(f.Query, "stacks", "")
f.Stack = true
case terms["panoramas"]:
f.Query = strings.ReplaceAll(f.Query, "panoramas", "")
f.Panorama = true
case terms["scans"]:
f.Query = strings.ReplaceAll(f.Query, "scans", "")
f.Scan = true
case terms["monochrome"]:
f.Query = strings.ReplaceAll(f.Query, "monochrome", "")
f.Mono = true
}
}
// Filter by location?
if f.Geo == true {
s = s.Where("photos.cell_id <> 'zz'")

View file

@ -202,3 +202,24 @@ func UniqueKeywords(s string) (results []string) {
func SortCaseInsensitive(words []string) {
sort.Slice(words, func(i, j int) bool { return strings.ToLower(words[i]) < strings.ToLower(words[j]) })
}
// SearchTerms returns a bool map with all terms as key.
func SearchTerms(s string) map[string]bool {
result := make(map[string]bool)
if s == "" {
return result
}
for _, w := range KeywordsRegexp.FindAllString(s, -1) {
w = strings.Trim(w, "- '")
if w == "" || len(w) < 2 && IsLatin(w) {
continue
}
result[w] = true
}
return result
}

View file

@ -212,3 +212,15 @@ func TestRemoveFromWords(t *testing.T) {
assert.Equal(t, []string{"apple", "brown", "jpg", "lazy"}, result)
})
}
func TestSearchTerms(t *testing.T) {
t.Run("Many", func(t *testing.T) {
result := SearchTerms("I'm a lazy-BRoWN fox! Yellow banana, apple; pan-pot b&w")
assert.Len(t, result, 7)
assert.Equal(t, map[string]bool{"I'm": true, "Yellow": true, "apple": true, "banana": true, "fox": true, "lazy-BRoWN": true, "pan-pot": true}, result)
})
t.Run("Empty", func(t *testing.T) {
result := SearchTerms("")
assert.Len(t, result, 0)
})
}