From 07d3bdbe723b9eb30ae3f676efbfc666073ec86d Mon Sep 17 00:00:00 2001 From: Scott Lepper Date: Thu, 9 Jan 2025 16:45:04 -0500 Subject: [PATCH] [search] - filter by starred (#98651) [search] - filter by starred --- pkg/registry/apis/dashboard/search.go | 14 ++++++++++++++ pkg/storage/unified/resource/document.go | 6 +++--- pkg/storage/unified/resource/document_test.go | 2 +- pkg/storage/unified/search/bleve.go | 1 + pkg/storage/unified/search/bleve_mappings.go | 15 +++++++++------ pkg/storage/unified/search/bleve_mappings_test.go | 2 +- pkg/storage/unified/search/bleve_test.go | 7 +++++-- .../search/testdata/doc/dashboard-aaa-out.json | 2 +- .../search/testdata/doc/folder-aaa-out.json | 2 +- .../search/testdata/doc/folder-bbb-out.json | 2 +- .../search/testdata/doc/playlist-aaa-out.json | 2 +- .../search/testdata/doc/report-aaa-out.json | 2 +- .../unified/search/testdata/manual-dashboard.json | 12 ++++++------ .../unified/search/testdata/manual-folder.json | 8 ++++---- public/app/features/search/service/types.ts | 1 + public/app/features/search/service/unified.ts | 11 ++++++++--- 16 files changed, 58 insertions(+), 31 deletions(-) diff --git a/pkg/registry/apis/dashboard/search.go b/pkg/registry/apis/dashboard/search.go index 86427079b78..4818b9971cd 100644 --- a/pkg/registry/apis/dashboard/search.go +++ b/pkg/registry/apis/dashboard/search.go @@ -303,6 +303,20 @@ func (s *SearchHandler) DoSearch(w http.ResponseWriter, r *http.Request) { }} } + // The names filter + names, ok := queryParams["name"] + if ok { + if searchRequest.Options.Fields == nil { + searchRequest.Options.Fields = []*resource.Requirement{} + } + namesFilter := []*resource.Requirement{{ + Key: "name", + Operator: "in", + Values: names, + }} + searchRequest.Options.Fields = append(searchRequest.Options.Fields, namesFilter...) + } + // Run the query result, err := s.client.Search(ctx, searchRequest) if err != nil { diff --git a/pkg/storage/unified/resource/document.go b/pkg/storage/unified/resource/document.go index 4ca6933b1bb..dbe12cc35b5 100644 --- a/pkg/storage/unified/resource/document.go +++ b/pkg/storage/unified/resource/document.go @@ -53,8 +53,8 @@ type IndexableDocument struct { // The resource key Key *ResourceKey `json:"key"` - // The resource type ( for federated indexes ) - Kind string `json:"kind,omitempty"` + // The k8s name + Name string `json:"name,omitempty"` // Resource version for the resource (if known) RV int64 `json:"rv,omitempty"` @@ -164,8 +164,8 @@ func NewIndexableDocument(key *ResourceKey, rv int64, obj utils.GrafanaMetaAcces } doc := &IndexableDocument{ Key: key, - Kind: key.Resource, RV: rv, + Name: key.Name, Title: title, // We always want *something* to display TitleSort: strings.ToLower(title), // Lowercase for case-insensitive sorting Labels: obj.GetLabels(), diff --git a/pkg/storage/unified/resource/document_test.go b/pkg/storage/unified/resource/document_test.go index 7544bdfc967..f382a01a0d1 100644 --- a/pkg/storage/unified/resource/document_test.go +++ b/pkg/storage/unified/resource/document_test.go @@ -33,13 +33,13 @@ func TestStandardDocumentBuilder(t *testing.T) { "resource": "playlists", "name": "test1" }, - "kind": "playlists", "rv": 10, "title": "test playlist unified storage", "title_sort": "test playlist unified storage", "created": 1717236672000, "createdBy": "user:ABC", "updatedBy": "user:XYZ", + "name": "test1", "repository": { "name": "SQL", "path": "15", diff --git a/pkg/storage/unified/search/bleve.go b/pkg/storage/unified/search/bleve.go index ec4d2d64b8e..c103305d45b 100644 --- a/pkg/storage/unified/search/bleve.go +++ b/pkg/storage/unified/search/bleve.go @@ -487,6 +487,7 @@ func requirementQuery(req *resource.Requirement, prefix string) (query.Query, *r if len(req.Values) == 0 { return query.NewMatchAllQuery(), nil } + if len(req.Values[0]) == 1 { q := query.NewMatchQuery(req.Values[0]) q.FieldVal = prefix + req.Key diff --git a/pkg/storage/unified/search/bleve_mappings.go b/pkg/storage/unified/search/bleve_mappings.go index a9d02817d60..3fb044e7a3b 100644 --- a/pkg/storage/unified/search/bleve_mappings.go +++ b/pkg/storage/unified/search/bleve_mappings.go @@ -17,6 +17,13 @@ func getBleveMappings(fields resource.SearchableDocumentFields) mapping.IndexMap func getBleveDocMappings(_ resource.SearchableDocumentFields) *mapping.DocumentMapping { mapper := bleve.NewDocumentStaticMapping() + nameMapping := &mapping.FieldMapping{ + Analyzer: keyword.Name, + Type: "text", + Index: true, + } + mapper.AddFieldMappingsAt(resource.SEARCH_FIELD_NAME, nameMapping) + // for sorting by title titleSortMapping := bleve.NewKeywordFieldMapping() mapper.AddFieldMappingsAt(resource.SEARCH_FIELD_TITLE_SORT, titleSortMapping) @@ -25,10 +32,6 @@ func getBleveDocMappings(_ resource.SearchableDocumentFields) *mapping.DocumentM titleSearchMapping := bleve.NewTextFieldMapping() mapper.AddFieldMappingsAt(resource.SEARCH_FIELD_TITLE, titleSearchMapping) - // for filtering by kind/resource ( federated search ) - kindMapping := bleve.NewTextFieldMapping() - mapper.AddFieldMappingsAt(resource.SEARCH_FIELD_KIND, kindMapping) - descriptionMapping := &mapping.FieldMapping{ Name: resource.SEARCH_FIELD_DESCRIPTION, Type: "text", @@ -76,8 +79,8 @@ func getBleveDocMappings(_ resource.SearchableDocumentFields) *mapping.DocumentM } mapper.AddFieldMappingsAt(resource.SEARCH_FIELD_REPOSITORY, repoMapping) - // TODO: we use the static mapper. why set dynamic to true? - mapper.Dynamic = true + labelMapper := bleve.NewDocumentMapping() + mapper.AddSubDocumentMapping(resource.SEARCH_FIELD_LABELS, labelMapper) return mapper } diff --git a/pkg/storage/unified/search/bleve_mappings_test.go b/pkg/storage/unified/search/bleve_mappings_test.go index f9a6c71c2f7..2f289dea756 100644 --- a/pkg/storage/unified/search/bleve_mappings_test.go +++ b/pkg/storage/unified/search/bleve_mappings_test.go @@ -42,5 +42,5 @@ func TestDocumentMapping(t *testing.T) { fmt.Printf("DOC: fields %d\n", len(doc.Fields)) fmt.Printf("DOC: size %d\n", doc.Size()) - require.Equal(t, 17, len(doc.Fields)) + require.Equal(t, 12, len(doc.Fields)) } diff --git a/pkg/storage/unified/search/bleve_test.go b/pkg/storage/unified/search/bleve_test.go index b3b9873646f..b20287a3169 100644 --- a/pkg/storage/unified/search/bleve_test.go +++ b/pkg/storage/unified/search/bleve_test.go @@ -62,7 +62,8 @@ func TestBleveBackend(t *testing.T) { Resource: key.Resource, }, 2, rv, info.Fields, func(index resource.ResourceIndex) (int64, error) { _ = index.Write(&resource.IndexableDocument{ - RV: 1, + RV: 1, + Name: "aaa", Key: &resource.ResourceKey{ Name: "aaa", Namespace: "ns", @@ -83,7 +84,8 @@ func TestBleveBackend(t *testing.T) { Tags: []string{"aa", "bb"}, }) _ = index.Write(&resource.IndexableDocument{ - RV: 2, + RV: 2, + Name: "bbb", Key: &resource.ResourceKey{ Name: "bbb", Namespace: "ns", @@ -112,6 +114,7 @@ func TestBleveBackend(t *testing.T) { Group: "dashboard.grafana.app", Resource: "dashboards", }, + Name: "ccc", Title: "ccc (dash)", TitleSort: "ccc (dash)", Folder: "zzz", diff --git a/pkg/storage/unified/search/testdata/doc/dashboard-aaa-out.json b/pkg/storage/unified/search/testdata/doc/dashboard-aaa-out.json index 9a139b8446a..cf5f5485a95 100644 --- a/pkg/storage/unified/search/testdata/doc/dashboard-aaa-out.json +++ b/pkg/storage/unified/search/testdata/doc/dashboard-aaa-out.json @@ -5,7 +5,7 @@ "resource": "dashboards", "name": "aaa" }, - "kind": "dashboards", + "name": "aaa", "rv": 1234, "title": "Test title", "title_sort": "test title", diff --git a/pkg/storage/unified/search/testdata/doc/folder-aaa-out.json b/pkg/storage/unified/search/testdata/doc/folder-aaa-out.json index 022e9dec18e..867c2bfa1ea 100644 --- a/pkg/storage/unified/search/testdata/doc/folder-aaa-out.json +++ b/pkg/storage/unified/search/testdata/doc/folder-aaa-out.json @@ -5,7 +5,7 @@ "resource": "dashboards", "name": "aaa" }, - "kind": "dashboards", + "name": "aaa", "rv": 1234, "title": "test-aaa", "title_sort": "test-aaa", diff --git a/pkg/storage/unified/search/testdata/doc/folder-bbb-out.json b/pkg/storage/unified/search/testdata/doc/folder-bbb-out.json index dfdfe7da4f5..e3dcd3021c9 100644 --- a/pkg/storage/unified/search/testdata/doc/folder-bbb-out.json +++ b/pkg/storage/unified/search/testdata/doc/folder-bbb-out.json @@ -5,7 +5,7 @@ "resource": "dashboards", "name": "bbb" }, - "kind": "dashboards", + "name": "bbb", "rv": 1234, "title": "test-bbb", "title_sort": "test-bbb", diff --git a/pkg/storage/unified/search/testdata/doc/playlist-aaa-out.json b/pkg/storage/unified/search/testdata/doc/playlist-aaa-out.json index de3d5e3ea91..235ec31e336 100644 --- a/pkg/storage/unified/search/testdata/doc/playlist-aaa-out.json +++ b/pkg/storage/unified/search/testdata/doc/playlist-aaa-out.json @@ -5,7 +5,7 @@ "resource": "dashboards", "name": "aaa" }, - "kind": "dashboards", + "name": "aaa", "rv": 1234, "title": "Test AAA", "title_sort": "test aaa", diff --git a/pkg/storage/unified/search/testdata/doc/report-aaa-out.json b/pkg/storage/unified/search/testdata/doc/report-aaa-out.json index e8c6945a1b9..0280c35f574 100644 --- a/pkg/storage/unified/search/testdata/doc/report-aaa-out.json +++ b/pkg/storage/unified/search/testdata/doc/report-aaa-out.json @@ -5,7 +5,7 @@ "resource": "dashboards", "name": "aaa" }, - "kind": "dashboards", + "name": "aaa", "rv": 1234, "title": "Test AAA", "title_sort": "test aaa", diff --git a/pkg/storage/unified/search/testdata/manual-dashboard.json b/pkg/storage/unified/search/testdata/manual-dashboard.json index 3730e1017a9..5df8ab5def2 100644 --- a/pkg/storage/unified/search/testdata/manual-dashboard.json +++ b/pkg/storage/unified/search/testdata/manual-dashboard.json @@ -74,8 +74,8 @@ "aa" ], "zzz", - 3, - 0, + null, + null, null, null, null @@ -98,8 +98,8 @@ "aa" ], "xxx", - 2, - 0, + null, + null, null, null, null @@ -123,8 +123,8 @@ "bb" ], "xxx", - 1, - 0, + null, + null, null, null, null diff --git a/pkg/storage/unified/search/testdata/manual-folder.json b/pkg/storage/unified/search/testdata/manual-folder.json index 0bc275487e3..06e8b593eba 100644 --- a/pkg/storage/unified/search/testdata/manual-folder.json +++ b/pkg/storage/unified/search/testdata/manual-folder.json @@ -51,8 +51,8 @@ "yyy (folder)", null, null, - 2, - 0 + null, + null ], "object": { "kind": "folders", @@ -70,8 +70,8 @@ "zzz (folder)", null, null, - 1, - 0 + null, + null ], "object": { "kind": "folders", diff --git a/public/app/features/search/service/types.ts b/public/app/features/search/service/types.ts index 83ceeb6758a..387bbfc66ef 100644 --- a/public/app/features/search/service/types.ts +++ b/public/app/features/search/service/types.ts @@ -17,6 +17,7 @@ export interface SearchQuery { tags?: string[]; kind?: string[]; panel_type?: string; + name?: string[]; uid?: string[]; facet?: FacetField[]; explain?: boolean; diff --git a/public/app/features/search/service/unified.ts b/public/app/features/search/service/unified.ts index 40f57501b1e..04f4be200c5 100644 --- a/public/app/features/search/service/unified.ts +++ b/public/app/features/search/service/unified.ts @@ -72,10 +72,11 @@ export class UnifiedSearcher implements GrafanaSearcher { throw new Error('facets not supported!'); } // get the starred dashboards - const starsUIDS = await getBackendSrv().get('api/user/stars'); - if (starsUIDS?.length) { + const starsIds = await getBackendSrv().get('api/user/stars'); + if (starsIds?.length) { return this.doSearchQuery({ - uid: starsUIDS, + ...query, + name: starsIds, query: query.query ?? '*', }); } @@ -223,6 +224,10 @@ export class UnifiedSearcher implements GrafanaSearcher { const sort = query.sort.replace('_sort', '').replace('name', 'title'); uri += `&sort=${sort}`; } + + if (query.name?.length) { + uri += '&' + query.name.map((name) => `name=${encodeURIComponent(name)}`).join('&'); + } return uri; }