Search: Improvements for starred dashboard search (#64758)

* improvements for starred dashboard search

* fix workflows for the case when no dashboards are starred

* PR feedback (don't query DB if starred dashboards and requested but no starred IDs are found) and linting

* return empty list not null in case of no starred dashboards

* return empty list not null in case of no starred dashboards pt 2

* return empty list not null in case of no starred dashboards pt 3
This commit is contained in:
Ieva
2023-03-16 09:20:07 +00:00
committed by GitHub
parent 8617ad688d
commit f966045129
9 changed files with 107 additions and 102 deletions

View File

@@ -58,10 +58,30 @@ type SearchService struct {
}
func (s *SearchService) SearchHandler(ctx context.Context, query *Query) error {
starredQuery := star.GetUserStarsQuery{
UserID: query.SignedInUser.UserID,
}
staredDashIDs, err := s.starService.GetByUser(ctx, &starredQuery)
if err != nil {
return err
}
// No starred dashboards will be found
if query.IsStarred && len(staredDashIDs.UserStars) == 0 {
query.Result = model.HitList{}
return nil
}
// filter by starred dashboard IDs when starred dashboards are requested and no UID or ID filters are specified to improve query performance
if query.IsStarred && len(query.DashboardIds) == 0 && len(query.DashboardUIDs) == 0 {
for id := range staredDashIDs.UserStars {
query.DashboardIds = append(query.DashboardIds, id)
}
}
dashboardQuery := dashboards.FindPersistedDashboardsQuery{
Title: query.Title,
SignedInUser: query.SignedInUser,
IsStarred: query.IsStarred,
DashboardUIDs: query.DashboardUIDs,
DashboardIds: query.DashboardIds,
Type: query.Type,
@@ -85,11 +105,24 @@ func (s *SearchService) SearchHandler(ctx context.Context, query *Query) error {
hits = sortedHits(hits)
}
if err := s.setStarredDashboards(ctx, query.SignedInUser.UserID, hits); err != nil {
return err
// set starred dashboards
for _, dashboard := range hits {
if _, ok := staredDashIDs.UserStars[dashboard.ID]; ok {
dashboard.IsStarred = true
}
}
query.Result = hits
// filter for starred dashboards if requested
if !query.IsStarred {
query.Result = hits
} else {
query.Result = model.HitList{}
for _, dashboard := range hits {
if dashboard.IsStarred {
query.Result = append(query.Result, dashboard)
}
}
}
return nil
}
@@ -106,22 +139,3 @@ func sortedHits(unsorted model.HitList) model.HitList {
return hits
}
func (s *SearchService) setStarredDashboards(ctx context.Context, userID int64, hits []*model.Hit) error {
query := star.GetUserStarsQuery{
UserID: userID,
}
res, err := s.starService.GetByUser(ctx, &query)
if err != nil {
return err
}
iuserstars := res.UserStars
for _, dashboard := range hits {
if _, ok := iuserstars[dashboard.ID]; ok {
dashboard.IsStarred = true
}
}
return nil
}

View File

@@ -62,3 +62,39 @@ func TestSearch_SortedResults(t *testing.T) {
assert.Equal(t, "BB", query.Result[3].Tags[1])
assert.Equal(t, "EE", query.Result[3].Tags[2])
}
func TestSearch_StarredResults(t *testing.T) {
ss := startest.NewStarServiceFake()
db := dbtest.NewFakeDB()
us := usertest.NewUserServiceFake()
ds := dashboards.NewFakeDashboardService(t)
ds.On("SearchDashboards", mock.Anything, mock.AnythingOfType("*dashboards.FindPersistedDashboardsQuery")).Run(func(args mock.Arguments) {
q := args.Get(1).(*dashboards.FindPersistedDashboardsQuery)
q.Result = model.HitList{
&model.Hit{ID: 1, Title: "A", Type: "dash-db"},
&model.Hit{ID: 2, Title: "B", Type: "dash-db"},
&model.Hit{ID: 3, Title: "C", Type: "dash-db"},
}
}).Return(nil)
us.ExpectedSignedInUser = &user.SignedInUser{}
ss.ExpectedUserStars = &star.GetUserStarsResult{UserStars: map[int64]bool{1: true, 3: true, 4: true}}
svc := &SearchService{
sqlstore: db,
starService: ss,
dashboardService: ds,
}
query := &Query{
Limit: 2000,
IsStarred: true,
SignedInUser: &user.SignedInUser{},
}
err := svc.SearchHandler(context.Background(), query)
require.Nil(t, err)
// Assert only starred dashboards are returned
assert.Equal(t, 2, query.Result.Len())
assert.Equal(t, "A", query.Result[0].Title)
assert.Equal(t, "C", query.Result[1].Title)
}