Skip to content

Commit cedda00

Browse files
committed
small speedup to search filter
removed LOWER() and CONCAT() which prevent to use indexes
1 parent 0e2f53d commit cedda00

2 files changed

Lines changed: 48 additions & 8 deletions

File tree

manager/controllers/utils.go

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -223,18 +223,15 @@ func UpdateMetaLinks(c *gin.Context, meta *ListMeta, total int, subTotals map[st
223223

224224
func ApplySearch(c *gin.Context, tx *gorm.DB, searchColumns ...string) (*gorm.DB, string) {
225225
search := base.RemoveInvalidChars(c.Query("search"))
226-
if search == "" {
226+
if search == "" || len(searchColumns) == 0 {
227227
return tx, ""
228228
}
229229

230-
if len(searchColumns) == 0 {
231-
return tx, ""
230+
or := database.DB
231+
for _, column := range searchColumns {
232+
or = or.Or(column+"::text ILIKE ?", "%"+search+"%")
232233
}
233-
234-
searchExtended := "%" + search + "%"
235-
concatValue := strings.Join(searchColumns, ",' ',")
236-
txWithSearch := tx.Where("LOWER(CONCAT("+concatValue+")) LIKE LOWER(?)", searchExtended)
237-
return txWithSearch, fmt.Sprintf("search=%s", search)
234+
return tx.Where(or), fmt.Sprintf("search=%s", search)
238235
}
239236

240237
type Tag struct {

manager/controllers/utils_test.go

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package controllers
22

33
import (
4+
"app/base/core"
45
"app/base/database"
56
"app/base/utils"
67
"net/http"
@@ -9,6 +10,7 @@ import (
910

1011
"github.com/gin-gonic/gin"
1112
"github.com/stretchr/testify/assert"
13+
"gorm.io/gorm"
1214
)
1315

1416
func TestGroupNameFilter(t *testing.T) {
@@ -54,3 +56,44 @@ func TestGroupNameFilter2(t *testing.T) {
5456

5557
assert.Equal(t, 9, len(systems)) // 2 systems with `group2`, 6 with `group1` in test_data
5658
}
59+
60+
func TestApplySearchEmpty(t *testing.T) {
61+
var baseTx gorm.DB
62+
63+
var cases = []struct {
64+
url string
65+
columns []string
66+
comment string
67+
}{
68+
{"/", []string{""}, "no search query returns original tx and empty meta"},
69+
{"/?search=", []string{"some_col"}, "empty search value returns original tx and empty meta"},
70+
{"/?search=foo", []string{}, "search present but no columns returns original tx and empty meta"},
71+
}
72+
for _, c := range cases {
73+
t.Run(c.comment, func(t *testing.T) {
74+
ctx, _ := gin.CreateTestContext(httptest.NewRecorder())
75+
ctx.Request, _ = http.NewRequest("GET", c.url, nil)
76+
outTx, q := ApplySearch(ctx, &baseTx, c.columns...)
77+
assert.Same(t, &baseTx, outTx)
78+
assert.Equal(t, "", q)
79+
})
80+
}
81+
}
82+
83+
func TestApplySearchHello(t *testing.T) {
84+
core.SetupTest(t)
85+
86+
c, _ := gin.CreateTestContext(httptest.NewRecorder())
87+
c.Request, _ = http.NewRequest("GET", "/?search=hello", nil)
88+
89+
tx, searchQ := ApplySearch(c, database.DB, "a", "b")
90+
assert.Equal(t, "search=hello", searchQ)
91+
92+
tx = tx.Where("1 = 0")
93+
var n string
94+
sql := tx.ToSQL(func(g *gorm.DB) *gorm.DB {
95+
return g.Table("(select 'a' as a, 'b' as b) as t").Select("a").Scan(&n)
96+
})
97+
98+
assert.Contains(t, sql, "WHERE (a::text ILIKE '%hello%' OR b::text ILIKE '%hello%')")
99+
}

0 commit comments

Comments
 (0)