mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
search: add OR filter for kinds (#95915)
search: add OR filter for kinds
This commit is contained in:
parent
cd9fcd08aa
commit
1feaf6df99
@ -5,6 +5,7 @@ import (
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
@ -106,7 +107,7 @@ func (b *SearchAPIBuilder) GetAPIRoutes() *builder.APIRoutes {
|
||||
|
||||
searchRequest := &resource.SearchRequest{
|
||||
Tenant: tenant,
|
||||
Kind: queryParams.Get("kind"),
|
||||
Kind: strings.Split(queryParams.Get("kind"), ","),
|
||||
QueryType: queryParams.Get("queryType"),
|
||||
Query: queryParams.Get("query"),
|
||||
Limit: int64(limit),
|
||||
|
@ -165,7 +165,7 @@ func (s *StandardSearchService) doSearchQuery(ctx context.Context, qry Query, _
|
||||
// will use stack id for cloud and org id for on-prem
|
||||
tenantId := request.GetNamespaceMapper(s.cfg)(orgID)
|
||||
|
||||
req := &resource.SearchRequest{Tenant: tenantId, Query: qry.Query, Limit: int64(qry.Limit), Offset: int64(qry.From)}
|
||||
req := &resource.SearchRequest{Tenant: tenantId, Query: qry.Query, Limit: int64(qry.Limit), Offset: int64(qry.From), Kind: qry.Kind}
|
||||
res, err := s.resourceClient.Search(ctx, req)
|
||||
if err != nil {
|
||||
s.logger.Error("Failed to search resources", "error", err)
|
||||
|
@ -269,7 +269,19 @@ func (i *Index) Search(ctx context.Context, request *SearchRequest) (*IndexResul
|
||||
request.Limit = 10
|
||||
}
|
||||
|
||||
query := bleve.NewQueryStringQuery(request.Query)
|
||||
textQuery := bleve.NewQueryStringQuery(request.Query)
|
||||
query := bleve.NewConjunctionQuery(textQuery)
|
||||
|
||||
if len(request.Kind) > 0 {
|
||||
// apply OR condition filter for each kind ( dashboard, folder, etc )
|
||||
orQuery := bleve.NewDisjunctionQuery()
|
||||
for _, term := range request.Kind {
|
||||
termQuery := bleve.NewTermQuery(term)
|
||||
orQuery.AddQuery(termQuery)
|
||||
}
|
||||
query.AddQuery(orQuery)
|
||||
}
|
||||
|
||||
req := bleve.NewSearchRequest(query)
|
||||
|
||||
for _, group := range request.GroupBy {
|
||||
@ -387,6 +399,12 @@ func fetchResourceTypes() []*ListOptions {
|
||||
Group: "folder.grafana.app",
|
||||
Resource: "folders",
|
||||
},
|
||||
})
|
||||
},
|
||||
&ListOptions{
|
||||
Key: &ResourceKey{
|
||||
Group: "dashboard.grafana.app",
|
||||
Resource: "dashboards",
|
||||
},
|
||||
})
|
||||
return items
|
||||
}
|
||||
|
@ -29,7 +29,7 @@ func TestIndexDashboard(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
assertCountEquals(t, index, 1)
|
||||
assertSearchCountEquals(t, index, "*", 1)
|
||||
assertSearchCountEquals(t, index, "*", nil, 1)
|
||||
}
|
||||
|
||||
func TestIndexFolder(t *testing.T) {
|
||||
@ -41,7 +41,7 @@ func TestIndexFolder(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
assertCountEquals(t, index, 1)
|
||||
assertSearchCountEquals(t, index, "*", 1)
|
||||
assertSearchCountEquals(t, index, "*", nil, 1)
|
||||
}
|
||||
|
||||
func TestSearchFolder(t *testing.T) {
|
||||
@ -54,7 +54,21 @@ func TestSearchFolder(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
assertCountEquals(t, index, 2)
|
||||
assertSearchCountEquals(t, index, "Kind:Folder", 1)
|
||||
assertSearchCountEquals(t, index, "*", []string{"folder"}, 1)
|
||||
}
|
||||
|
||||
func TestSearchDashboardsAndFoldersOnly(t *testing.T) {
|
||||
dashboard := readTestData(t, "dashboard-resource.json")
|
||||
folder := readTestData(t, "folder-resource.json")
|
||||
playlist := readTestData(t, "playlist-resource.json")
|
||||
list := &ListResponse{Items: []*ResourceWrapper{{Value: dashboard}, {Value: folder}, {Value: playlist}}}
|
||||
index := newTestIndex(t, 1)
|
||||
|
||||
err := index.writeBatch(testContext, list)
|
||||
require.NoError(t, err)
|
||||
|
||||
assertCountEquals(t, index, 3)
|
||||
assertSearchCountEquals(t, index, "*", []string{"dashboard", "folder"}, 2)
|
||||
}
|
||||
|
||||
func TestLookupNames(t *testing.T) {
|
||||
@ -75,7 +89,7 @@ func TestLookupNames(t *testing.T) {
|
||||
for _, id := range chunk {
|
||||
query += `"` + id + `" `
|
||||
}
|
||||
assertSearchCountEquals(t, index, query, int64(len(chunk)))
|
||||
assertSearchCountEquals(t, index, query, nil, int64(len(chunk)))
|
||||
}
|
||||
|
||||
func TestIndexDashboardWithTags(t *testing.T) {
|
||||
@ -88,8 +102,8 @@ func TestIndexDashboardWithTags(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
assertCountEquals(t, index, 2)
|
||||
assertSearchCountEquals(t, index, "tag1", 2)
|
||||
assertSearchCountEquals(t, index, "tag4", 1)
|
||||
assertSearchCountEquals(t, index, "tag1", nil, 2)
|
||||
assertSearchCountEquals(t, index, "tag4", nil, 1)
|
||||
assertSearchGroupCountEquals(t, index, "*", "tags", 4)
|
||||
assertSearchGroupCountEquals(t, index, "tag4", "tags", 3)
|
||||
}
|
||||
@ -187,8 +201,8 @@ func assertCountEquals(t *testing.T, index *Index, expected uint64) {
|
||||
assert.Equal(t, expected, total)
|
||||
}
|
||||
|
||||
func assertSearchCountEquals(t *testing.T, index *Index, search string, expected int64) {
|
||||
req := &SearchRequest{Query: search, Tenant: testTenant, Limit: expected + 1, Offset: 0}
|
||||
func assertSearchCountEquals(t *testing.T, index *Index, search string, kind []string, expected int64) {
|
||||
req := &SearchRequest{Query: search, Tenant: testTenant, Limit: expected + 1, Offset: 0, Kind: kind}
|
||||
start := time.Now()
|
||||
results, err := index.Search(testContext, req)
|
||||
require.NoError(t, err)
|
||||
|
@ -1633,7 +1633,7 @@ type SearchRequest struct {
|
||||
QueryType string `protobuf:"bytes,2,opt,name=queryType,proto3" json:"queryType,omitempty"`
|
||||
Tenant string `protobuf:"bytes,3,opt,name=tenant,proto3" json:"tenant,omitempty"`
|
||||
// resource kind (playlists, dashboards, etc)
|
||||
Kind string `protobuf:"bytes,4,opt,name=kind,proto3" json:"kind,omitempty"`
|
||||
Kind []string `protobuf:"bytes,4,rep,name=kind,proto3" json:"kind,omitempty"`
|
||||
// pagination support
|
||||
Limit int64 `protobuf:"varint,5,opt,name=limit,proto3" json:"limit,omitempty"`
|
||||
Offset int64 `protobuf:"varint,6,opt,name=offset,proto3" json:"offset,omitempty"`
|
||||
@ -1692,11 +1692,11 @@ func (x *SearchRequest) GetTenant() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *SearchRequest) GetKind() string {
|
||||
func (x *SearchRequest) GetKind() []string {
|
||||
if x != nil {
|
||||
return x.Kind
|
||||
}
|
||||
return ""
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *SearchRequest) GetLimit() int64 {
|
||||
@ -2916,7 +2916,7 @@ var file_resource_proto_rawDesc = []byte{
|
||||
0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x71, 0x75, 0x65, 0x72, 0x79,
|
||||
0x54, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x18, 0x03,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04,
|
||||
0x6b, 0x69, 0x6e, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6b, 0x69, 0x6e, 0x64,
|
||||
0x6b, 0x69, 0x6e, 0x64, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x6b, 0x69, 0x6e, 0x64,
|
||||
0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52,
|
||||
0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74,
|
||||
0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x2b,
|
||||
|
@ -330,7 +330,7 @@ message SearchRequest {
|
||||
string queryType = 2;
|
||||
string tenant = 3;
|
||||
// resource kind (playlists, dashboards, etc)
|
||||
string kind = 4;
|
||||
repeated string kind = 4;
|
||||
// pagination support
|
||||
int64 limit = 5;
|
||||
int64 offset = 6;
|
||||
|
19
pkg/storage/unified/resource/testdata/playlist-resource.json
vendored
Normal file
19
pkg/storage/unified/resource/testdata/playlist-resource.json
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
{
|
||||
"kind": "Playlist",
|
||||
"apiVersion": "playlist.grafana.app/v0alpha1",
|
||||
"metadata": {
|
||||
"name": "ae2ntrqxefvnke",
|
||||
"namespace": "default",
|
||||
"uid": "playlist-1",
|
||||
"creationTimestamp": "2024-11-01T19:42:22Z",
|
||||
"annotations": {
|
||||
"grafana.app/createdBy": "user:1",
|
||||
"grafana.app/originName": "SQL",
|
||||
"grafana.app/originPath": "15",
|
||||
"grafana.app/originTimestamp": "2024-11-01T19:42:22Z"
|
||||
}
|
||||
},
|
||||
"spec": {
|
||||
"title": "test-us-playlist"
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user