Search: Omit full text index if query is too short #1517

This commit is contained in:
Michael Mayer 2021-09-17 15:52:25 +02:00
parent 79961ec11b
commit 0f90258ef9
10 changed files with 52 additions and 10 deletions

View file

@ -15,6 +15,8 @@ import (
geojson "github.com/paulmach/go.geojson"
)
// GetGeo performs a geo search with reduced metadata details for improved performance.
//
// GET /api/v1/geo
func GetGeo(router *gin.RouterGroup) {
router.GET("/geo", func(c *gin.Context) {
@ -37,7 +39,8 @@ func GetGeo(router *gin.RouterGroup) {
photos, err := query.Geo(f)
if err != nil {
c.AbortWithStatusJSON(400, gin.H{"error": txt.UcFirst(err.Error())})
log.Warnf("search: %s", err)
AbortBadRequest(c)
return
}

View file

@ -61,7 +61,7 @@ func GetPhotos(router *gin.RouterGroup) {
result, count, err := query.PhotoSearch(f)
if err != nil {
log.Error(err)
log.Warnf("search: %s", err)
AbortBadRequest(c)
return
}

View file

@ -59,5 +59,5 @@ func Msg(id Message, params ...interface{}) string {
}
func Error(id Message, params ...interface{}) error {
return errors.New(Msg(id, params...))
return errors.New(strings.ToLower(Msg(id, params...)))
}

View file

@ -58,20 +58,20 @@ func TestMsg(t *testing.T) {
func TestError(t *testing.T) {
t.Run("already exists", func(t *testing.T) {
err := Error(ErrAlreadyExists, "A cat")
assert.EqualError(t, err, "A cat already exists")
assert.EqualError(t, err, "a cat already exists")
})
t.Run("unexpected error", func(t *testing.T) {
err := Error(ErrUnexpected, "A cat")
assert.EqualError(t, err, "Unexpected error, please try again")
assert.EqualError(t, err, "unexpected error, please try again")
})
t.Run("already exists german", func(t *testing.T) {
SetLocale("de")
errGerman := Error(ErrAlreadyExists, "Eine Katze")
assert.EqualError(t, errGerman, "Eine Katze existiert bereits")
assert.EqualError(t, errGerman, "eine katze existiert bereits")
SetLocale("")
errDefault := Error(ErrAlreadyExists, "A cat")
assert.EqualError(t, errDefault, "A cat already exists")
assert.EqualError(t, errDefault, "a cat already exists")
})
}

View file

@ -52,7 +52,10 @@ 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 {
if terms := txt.SearchTerms(f.Query); f.Query != "" && len(terms) == 0 {
f.Name = fs.StripKnownExt(f.Query) + "*"
f.Query = ""
} else if len(terms) > 0 {
switch {
case terms["faces"]:
f.Query = strings.ReplaceAll(f.Query, "faces", "")

View file

@ -23,6 +23,13 @@ func NormalizeSearchQuery(s string) string {
return strings.Trim(s, "+&|_-=!@$%^(){}\\<>,.;: ")
}
// IsTooShort tests if a search query is too short.
func IsTooShort(q string) bool {
q = strings.Trim(q, "- '")
return q != "" && len(q) < 3 && txt.IsLatin(q)
}
// LikeAny returns a single where condition matching the search words.
func LikeAny(col, s string, keywords, exact bool) (wheres []string) {
if s == "" {

View file

@ -13,6 +13,21 @@ func TestNormalizeSearchQuery(t *testing.T) {
})
}
func TestIsTooShort(t *testing.T) {
t.Run("Empty", func(t *testing.T) {
assert.False(t, IsTooShort(""))
})
t.Run("IsTooShort", func(t *testing.T) {
assert.True(t, IsTooShort("aa"))
})
t.Run("Chinese", func(t *testing.T) {
assert.False(t, IsTooShort("李"))
})
t.Run("OK", func(t *testing.T) {
assert.False(t, IsTooShort("foo"))
})
}
func TestLikeAny(t *testing.T) {
t.Run("and_or_search", func(t *testing.T) {
if w := LikeAny("k.keyword", "table spoon & usa | img json", true, false); len(w) != 2 {

View file

@ -145,7 +145,10 @@ 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 {
if terms := txt.SearchTerms(f.Query); f.Query != "" && len(terms) == 0 {
f.Name = fs.StripKnownExt(f.Query) + "*"
f.Query = ""
} else if len(terms) > 0 {
switch {
case terms["faces"]:
f.Query = strings.ReplaceAll(f.Query, "faces", "")

View file

@ -11,6 +11,17 @@ import (
)
func TestPhotoSearch(t *testing.T) {
t.Run("Chinese", func(t *testing.T) {
var frm form.PhotoSearch
frm.Query = "张"
frm.Count = 10
frm.Offset = 0
_, _, err := PhotoSearch(frm)
assert.NoError(t, err)
})
t.Run("search all", func(t *testing.T) {
var frm form.PhotoSearch

View file

@ -214,7 +214,7 @@ func SearchTerms(s string) map[string]bool {
for _, w := range KeywordsRegexp.FindAllString(s, -1) {
w = strings.Trim(w, "- '")
if w == "" || len(w) < 2 && IsLatin(w) {
if w == "" || len(w) < 3 && IsLatin(w) {
continue
}