mirror of
https://github.com/grafana/grafana.git
synced 2025-08-02 10:18:29 +08:00
@ -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 {
|
||||
|
@ -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(),
|
||||
|
@ -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",
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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))
|
||||
}
|
||||
|
@ -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",
|
||||
|
@ -5,7 +5,7 @@
|
||||
"resource": "dashboards",
|
||||
"name": "aaa"
|
||||
},
|
||||
"kind": "dashboards",
|
||||
"name": "aaa",
|
||||
"rv": 1234,
|
||||
"title": "Test title",
|
||||
"title_sort": "test title",
|
||||
|
@ -5,7 +5,7 @@
|
||||
"resource": "dashboards",
|
||||
"name": "aaa"
|
||||
},
|
||||
"kind": "dashboards",
|
||||
"name": "aaa",
|
||||
"rv": 1234,
|
||||
"title": "test-aaa",
|
||||
"title_sort": "test-aaa",
|
||||
|
@ -5,7 +5,7 @@
|
||||
"resource": "dashboards",
|
||||
"name": "bbb"
|
||||
},
|
||||
"kind": "dashboards",
|
||||
"name": "bbb",
|
||||
"rv": 1234,
|
||||
"title": "test-bbb",
|
||||
"title_sort": "test-bbb",
|
||||
|
@ -5,7 +5,7 @@
|
||||
"resource": "dashboards",
|
||||
"name": "aaa"
|
||||
},
|
||||
"kind": "dashboards",
|
||||
"name": "aaa",
|
||||
"rv": 1234,
|
||||
"title": "Test AAA",
|
||||
"title_sort": "test aaa",
|
||||
|
@ -5,7 +5,7 @@
|
||||
"resource": "dashboards",
|
||||
"name": "aaa"
|
||||
},
|
||||
"kind": "dashboards",
|
||||
"name": "aaa",
|
||||
"rv": 1234,
|
||||
"title": "Test AAA",
|
||||
"title_sort": "test aaa",
|
||||
|
@ -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
|
||||
|
@ -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",
|
||||
|
@ -17,6 +17,7 @@ export interface SearchQuery {
|
||||
tags?: string[];
|
||||
kind?: string[];
|
||||
panel_type?: string;
|
||||
name?: string[];
|
||||
uid?: string[];
|
||||
facet?: FacetField[];
|
||||
explain?: boolean;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user