mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
[search] title phrase (#99753)
[search] rename title_sort to title_phrase
This commit is contained in:
parent
cf177776bf
commit
8e9e3b8362
@ -240,9 +240,9 @@ func (s *Service) getFolderByTitleFromApiServer(ctx context.Context, orgID int64
|
||||
Key: folderkey,
|
||||
Fields: []*resource.Requirement{
|
||||
{
|
||||
Key: resource.SEARCH_FIELD_TITLE_SORT,
|
||||
Key: resource.SEARCH_FIELD_TITLE_PHRASE,
|
||||
Operator: string(selection.In),
|
||||
Values: []string{strings.ToLower(title)},
|
||||
Values: []string{title},
|
||||
},
|
||||
},
|
||||
Labels: []*resource.Requirement{},
|
||||
|
@ -567,7 +567,7 @@ func (r resourceClientMock) Search(ctx context.Context, in *resource.ResourceSea
|
||||
}
|
||||
|
||||
if len(in.Options.Fields) > 0 &&
|
||||
in.Options.Fields[0].Key == resource.SEARCH_FIELD_TITLE_SORT &&
|
||||
in.Options.Fields[0].Key == resource.SEARCH_FIELD_TITLE_PHRASE &&
|
||||
in.Options.Fields[0].Operator == "in" &&
|
||||
len(in.Options.Fields[0].Values) > 0 &&
|
||||
in.Options.Fields[0].Values[0] == "foo" {
|
||||
|
@ -63,7 +63,7 @@ type IndexableDocument struct {
|
||||
Title string `json:"title,omitempty"`
|
||||
|
||||
// internal sort field for title ( don't set this directly )
|
||||
TitleSort string `json:"title_sort,omitempty"`
|
||||
TitlePhrase string `json:"title_phrase,omitempty"`
|
||||
|
||||
// A generic description -- helpful in global search
|
||||
Description string `json:"description,omitempty"`
|
||||
@ -163,15 +163,15 @@ func NewIndexableDocument(key *ResourceKey, rv int64, obj utils.GrafanaMetaAcces
|
||||
}
|
||||
}
|
||||
doc := &IndexableDocument{
|
||||
Key: key,
|
||||
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(),
|
||||
Folder: obj.GetFolder(),
|
||||
CreatedBy: obj.GetCreatedBy(),
|
||||
UpdatedBy: obj.GetUpdatedBy(),
|
||||
Key: key,
|
||||
RV: rv,
|
||||
Name: key.Name,
|
||||
Title: title, // We always want *something* to display
|
||||
TitlePhrase: strings.ToLower(title), // Lowercase for case-insensitive sorting
|
||||
Labels: obj.GetLabels(),
|
||||
Folder: obj.GetFolder(),
|
||||
CreatedBy: obj.GetCreatedBy(),
|
||||
UpdatedBy: obj.GetUpdatedBy(),
|
||||
}
|
||||
doc.RepoInfo, _ = obj.GetRepositoryInfo()
|
||||
ts := obj.GetCreationTimestamp()
|
||||
@ -253,7 +253,7 @@ const SEARCH_FIELD_NAMESPACE = "namespace"
|
||||
const SEARCH_FIELD_NAME = "name"
|
||||
const SEARCH_FIELD_RV = "rv"
|
||||
const SEARCH_FIELD_TITLE = "title"
|
||||
const SEARCH_FIELD_TITLE_SORT = "title_sort"
|
||||
const SEARCH_FIELD_TITLE_PHRASE = "title_phrase" // filtering/sorting on title by full phrase
|
||||
const SEARCH_FIELD_DESCRIPTION = "description"
|
||||
const SEARCH_FIELD_TAGS = "tags"
|
||||
const SEARCH_FIELD_LABELS = "labels" // All labels, not a specific one
|
||||
|
@ -35,7 +35,7 @@ func TestStandardDocumentBuilder(t *testing.T) {
|
||||
},
|
||||
"rv": 10,
|
||||
"title": "test playlist unified storage",
|
||||
"title_sort": "test playlist unified storage",
|
||||
"title_phrase": "test playlist unified storage",
|
||||
"created": 1717236672000,
|
||||
"createdBy": "user:ABC",
|
||||
"updatedBy": "user:XYZ",
|
||||
|
@ -1284,12 +1284,12 @@ type ListOptions struct {
|
||||
// Group+Namespace+Resource (not name)
|
||||
Key *ResourceKey `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"`
|
||||
// (best effort) Match label
|
||||
// Allowed to send more results than actually match because the filter will be appled
|
||||
// to the resutls agin in the client. That time with the full field selector
|
||||
// Allowed to send more results than actually match because the filter will be applied
|
||||
// to the results again in the client. That time with the full field selector
|
||||
Labels []*Requirement `protobuf:"bytes,2,rep,name=labels,proto3" json:"labels,omitempty"`
|
||||
// (best effort) fields matcher
|
||||
// Allowed to send more results than actually match because the filter will be appled
|
||||
// to the resutls agin in the client. That time with the full field selector
|
||||
// Allowed to send more results than actually match because the filter will be applied
|
||||
// to the results again in the client. That time with the full field selector
|
||||
Fields []*Requirement `protobuf:"bytes,3,rep,name=fields,proto3" json:"fields,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
|
@ -209,13 +209,13 @@ message ListOptions {
|
||||
ResourceKey key = 1;
|
||||
|
||||
// (best effort) Match label
|
||||
// Allowed to send more results than actually match because the filter will be appled
|
||||
// to the resutls agin in the client. That time with the full field selector
|
||||
// Allowed to send more results than actually match because the filter will be applied
|
||||
// to the results again in the client. That time with the full field selector
|
||||
repeated Requirement labels = 2;
|
||||
|
||||
// (best effort) fields matcher
|
||||
// Allowed to send more results than actually match because the filter will be appled
|
||||
// to the resutls agin in the client. That time with the full field selector
|
||||
// Allowed to send more results than actually match because the filter will be applied
|
||||
// to the results again in the client. That time with the full field selector
|
||||
repeated Requirement fields = 3;
|
||||
}
|
||||
|
||||
|
@ -684,9 +684,11 @@ func getSortFields(req *resource.ResourceSearchRequest) []string {
|
||||
|
||||
// fields that we went to sort by the full text
|
||||
var textSortFields = map[string]string{
|
||||
resource.SEARCH_FIELD_TITLE: resource.SEARCH_FIELD_TITLE + "_sort",
|
||||
resource.SEARCH_FIELD_TITLE: resource.SEARCH_FIELD_TITLE_PHRASE,
|
||||
}
|
||||
|
||||
const lowerCase = "phrase"
|
||||
|
||||
// Convert a "requirement" into a bleve query
|
||||
func requirementQuery(req *resource.Requirement, prefix string) (query.Query, *resource.ErrorResult) {
|
||||
switch selection.Operator(req.Operator) {
|
||||
@ -696,14 +698,14 @@ func requirementQuery(req *resource.Requirement, prefix string) (query.Query, *r
|
||||
}
|
||||
|
||||
if len(req.Values[0]) == 1 {
|
||||
q := query.NewMatchQuery(req.Values[0])
|
||||
q := query.NewMatchQuery(filterValue(req.Key, req.Values[0]))
|
||||
q.FieldVal = prefix + req.Key
|
||||
return q, nil
|
||||
}
|
||||
|
||||
conjuncts := []query.Query{}
|
||||
for _, v := range req.Values {
|
||||
q := query.NewMatchQuery(v)
|
||||
q := query.NewMatchQuery(filterValue(req.Key, v))
|
||||
q.FieldVal = prefix + req.Key
|
||||
conjuncts = append(conjuncts, q)
|
||||
}
|
||||
@ -720,14 +722,14 @@ func requirementQuery(req *resource.Requirement, prefix string) (query.Query, *r
|
||||
return query.NewMatchAllQuery(), nil
|
||||
}
|
||||
if len(req.Values) == 1 {
|
||||
q := query.NewMatchQuery(req.Values[0])
|
||||
q := query.NewMatchQuery(filterValue(req.Key, req.Values[0]))
|
||||
q.FieldVal = prefix + req.Key
|
||||
return q, nil
|
||||
}
|
||||
|
||||
disjuncts := []query.Query{}
|
||||
for _, v := range req.Values {
|
||||
q := query.NewMatchQuery(v)
|
||||
q := query.NewMatchQuery(filterValue(req.Key, v))
|
||||
q.FieldVal = prefix + req.Key
|
||||
disjuncts = append(disjuncts, q)
|
||||
}
|
||||
@ -739,7 +741,7 @@ func requirementQuery(req *resource.Requirement, prefix string) (query.Query, *r
|
||||
|
||||
var mustNotQueries []query.Query
|
||||
for _, value := range req.Values {
|
||||
mustNotQueries = append(mustNotQueries, bleve.NewMatchQuery(value))
|
||||
mustNotQueries = append(mustNotQueries, bleve.NewMatchQuery(filterValue(req.Key, value)))
|
||||
}
|
||||
boolQuery.AddMustNot(mustNotQueries...)
|
||||
|
||||
@ -754,6 +756,14 @@ func requirementQuery(req *resource.Requirement, prefix string) (query.Query, *r
|
||||
)
|
||||
}
|
||||
|
||||
// filterValue will convert the value to lower case if the field is a phrase field
|
||||
func filterValue(field string, v string) string {
|
||||
if strings.HasSuffix(field, lowerCase) {
|
||||
return strings.ToLower(v)
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
func (b *bleveIndex) hitsToTable(ctx context.Context, selectFields []string, hits search.DocumentMatchCollection, explain bool) (*resource.ResourceTable, error) {
|
||||
_, span := b.tracing.Start(ctx, tracingPrexfixBleve+"hitsToTable")
|
||||
defer span.End()
|
||||
|
@ -24,11 +24,12 @@ func getBleveDocMappings(_ resource.SearchableDocumentFields) *mapping.DocumentM
|
||||
}
|
||||
mapper.AddFieldMappingsAt(resource.SEARCH_FIELD_NAME, nameMapping)
|
||||
|
||||
// for sorting by title
|
||||
titleSortMapping := bleve.NewKeywordFieldMapping()
|
||||
mapper.AddFieldMappingsAt(resource.SEARCH_FIELD_TITLE_SORT, titleSortMapping)
|
||||
// for filtering/sorting by title full phrase
|
||||
titlePhraseMapping := bleve.NewKeywordFieldMapping()
|
||||
mapper.AddFieldMappingsAt(resource.SEARCH_FIELD_TITLE_PHRASE, titlePhraseMapping)
|
||||
|
||||
// for searching by title
|
||||
// TODO: do we still need this since we have SEARCH_FIELD_TITLE_PHRASE?
|
||||
titleSearchMapping := bleve.NewTextFieldMapping()
|
||||
mapper.AddFieldMappingsAt(resource.SEARCH_FIELD_TITLE, titleSearchMapping)
|
||||
|
||||
|
@ -78,9 +78,9 @@ func TestBleveBackend(t *testing.T) {
|
||||
Group: "dashboard.grafana.app",
|
||||
Resource: "dashboards",
|
||||
},
|
||||
Title: "aaa (dash)",
|
||||
TitleSort: "aaa (dash)",
|
||||
Folder: "xxx",
|
||||
Title: "aaa (dash)",
|
||||
TitlePhrase: "aaa (dash)",
|
||||
Folder: "xxx",
|
||||
Fields: map[string]any{
|
||||
DASHBOARD_PANEL_TYPES: []string{"timeseries", "table"},
|
||||
DASHBOARD_ERRORS_TODAY: 25,
|
||||
@ -106,9 +106,9 @@ func TestBleveBackend(t *testing.T) {
|
||||
Group: "dashboard.grafana.app",
|
||||
Resource: "dashboards",
|
||||
},
|
||||
Title: "bbb (dash)",
|
||||
TitleSort: "bbb (dash)",
|
||||
Folder: "xxx",
|
||||
Title: "bbb (dash)",
|
||||
TitlePhrase: "bbb (dash)",
|
||||
Folder: "xxx",
|
||||
Fields: map[string]any{
|
||||
DASHBOARD_PANEL_TYPES: []string{"timeseries"},
|
||||
DASHBOARD_ERRORS_TODAY: 40,
|
||||
@ -134,10 +134,10 @@ func TestBleveBackend(t *testing.T) {
|
||||
Group: "dashboard.grafana.app",
|
||||
Resource: "dashboards",
|
||||
},
|
||||
Name: "ccc",
|
||||
Title: "ccc (dash)",
|
||||
TitleSort: "ccc (dash)",
|
||||
Folder: "zzz",
|
||||
Name: "ccc",
|
||||
Title: "ccc (dash)",
|
||||
TitlePhrase: "ccc (dash)",
|
||||
Folder: "zzz",
|
||||
RepoInfo: &utils.ResourceRepositoryInfo{
|
||||
Name: "repo2",
|
||||
Path: "path/in/repo2.yaml",
|
||||
@ -332,8 +332,8 @@ func TestBleveBackend(t *testing.T) {
|
||||
Group: "folder.grafana.app",
|
||||
Resource: "folders",
|
||||
},
|
||||
Title: "zzz (folder)",
|
||||
TitleSort: "zzz (folder)",
|
||||
Title: "zzz (folder)",
|
||||
TitlePhrase: "zzz (folder)",
|
||||
RepoInfo: &utils.ResourceRepositoryInfo{
|
||||
Name: "repo-1",
|
||||
Path: "path/to/folder.json",
|
||||
@ -349,8 +349,8 @@ func TestBleveBackend(t *testing.T) {
|
||||
Group: "folder.grafana.app",
|
||||
Resource: "folders",
|
||||
},
|
||||
Title: "yyy (folder)",
|
||||
TitleSort: "yyy (folder)",
|
||||
Title: "yyy (folder)",
|
||||
TitlePhrase: "yyy (folder)",
|
||||
Labels: map[string]string{
|
||||
"region": "west",
|
||||
},
|
||||
|
@ -8,7 +8,7 @@
|
||||
"name": "aaa",
|
||||
"rv": 1234,
|
||||
"title": "Test title",
|
||||
"title_sort": "test title",
|
||||
"title_phrase": "test title",
|
||||
"description": "test description",
|
||||
"tags": [
|
||||
"a",
|
||||
|
@ -8,7 +8,7 @@
|
||||
"name": "aaa",
|
||||
"rv": 1234,
|
||||
"title": "test-aaa",
|
||||
"title_sort": "test-aaa",
|
||||
"title_phrase": "test-aaa",
|
||||
"created": 1730490142000,
|
||||
"createdBy": "user:1",
|
||||
"repo": {
|
||||
|
@ -8,7 +8,7 @@
|
||||
"name": "bbb",
|
||||
"rv": 1234,
|
||||
"title": "test-bbb",
|
||||
"title_sort": "test-bbb",
|
||||
"title_phrase": "test-bbb",
|
||||
"created": 1730490142000,
|
||||
"createdBy": "user:1",
|
||||
"repo": {
|
||||
|
@ -8,7 +8,7 @@
|
||||
"name": "aaa",
|
||||
"rv": 1234,
|
||||
"title": "Test AAA",
|
||||
"title_sort": "test aaa",
|
||||
"title_phrase": "test aaa",
|
||||
"created": 1731336353000,
|
||||
"createdBy": "user:t000000001",
|
||||
"repo": {
|
||||
|
@ -8,7 +8,7 @@
|
||||
"name": "aaa",
|
||||
"rv": 1234,
|
||||
"title": "Test AAA",
|
||||
"title_sort": "test aaa",
|
||||
"title_phrase": "test aaa",
|
||||
"labels": {
|
||||
"grafana.app/deprecatedInternalID": "123"
|
||||
},
|
||||
|
Loading…
Reference in New Issue
Block a user