search: add legacy id for all resources in bleve (#103206)

* add legacy id for all resources in bleve
pull/103257/head^2
Will Assis 3 months ago committed by GitHub
parent 2afeebec28
commit 08042ae827
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 6
      pkg/registry/apis/dashboard/legacysearcher/search_client.go
  2. 18
      pkg/registry/apis/dashboard/legacysearcher/search_client_test.go
  3. 3
      pkg/services/dashboards/service/dashboard_service.go
  4. 4
      pkg/services/dashboards/service/search/search_test.go
  5. 3
      pkg/services/folder/folderimpl/folder_unifiedstorage.go
  6. 3
      pkg/services/folder/folderimpl/unifiedstore.go
  7. 8
      pkg/storage/unified/resource/document.go
  8. 11
      pkg/storage/unified/search/bleve.go
  9. 6
      pkg/storage/unified/search/bleve_test.go
  10. 13
      pkg/storage/unified/search/dashboard.go
  11. 2
      pkg/storage/unified/search/testdata/doc/dashboard-aaa-out.json
  12. 18
      pkg/storage/unified/search/testdata/manual-dashboard.json
  13. 13
      pkg/storage/unified/search/testdata/manual-folder.json

@ -233,11 +233,7 @@ func (c *DashboardSearchClient) Search(ctx context.Context, req *resource.Resour
searchFields.Field(resource.SEARCH_FIELD_TITLE), searchFields.Field(resource.SEARCH_FIELD_TITLE),
searchFields.Field(resource.SEARCH_FIELD_FOLDER), searchFields.Field(resource.SEARCH_FIELD_FOLDER),
searchFields.Field(resource.SEARCH_FIELD_TAGS), searchFields.Field(resource.SEARCH_FIELD_TAGS),
{ searchFields.Field(resource.SEARCH_FIELD_LEGACY_ID),
Name: unisearch.DASHBOARD_LEGACY_ID,
Type: resource.ResourceTableColumnDefinition_INT64,
Description: "Deprecated legacy id of the dashboard",
},
} }
if sortByField != "" { if sortByField != "" {

@ -72,11 +72,7 @@ func TestDashboardSearchClient_Search(t *testing.T) {
searchFields.Field(resource.SEARCH_FIELD_TITLE), searchFields.Field(resource.SEARCH_FIELD_TITLE),
searchFields.Field(resource.SEARCH_FIELD_FOLDER), searchFields.Field(resource.SEARCH_FIELD_FOLDER),
searchFields.Field(resource.SEARCH_FIELD_TAGS), searchFields.Field(resource.SEARCH_FIELD_TAGS),
{ searchFields.Field(resource.SEARCH_FIELD_LEGACY_ID),
Name: unisearch.DASHBOARD_LEGACY_ID,
Type: resource.ResourceTableColumnDefinition_INT64,
Description: "Deprecated legacy id of the dashboard",
},
}, },
Rows: []*resource.ResourceTableRow{ Rows: []*resource.ResourceTableRow{
{ {
@ -149,11 +145,7 @@ func TestDashboardSearchClient_Search(t *testing.T) {
searchFields.Field(resource.SEARCH_FIELD_TITLE), searchFields.Field(resource.SEARCH_FIELD_TITLE),
searchFields.Field(resource.SEARCH_FIELD_FOLDER), searchFields.Field(resource.SEARCH_FIELD_FOLDER),
searchFields.Field(resource.SEARCH_FIELD_TAGS), searchFields.Field(resource.SEARCH_FIELD_TAGS),
{ searchFields.Field(resource.SEARCH_FIELD_LEGACY_ID),
Name: unisearch.DASHBOARD_LEGACY_ID,
Type: resource.ResourceTableColumnDefinition_INT64,
Description: "Deprecated legacy id of the dashboard",
},
{ {
Name: "views_total", Name: "views_total",
Type: resource.ResourceTableColumnDefinition_INT64, Type: resource.ResourceTableColumnDefinition_INT64,
@ -218,11 +210,7 @@ func TestDashboardSearchClient_Search(t *testing.T) {
searchFields.Field(resource.SEARCH_FIELD_TITLE), searchFields.Field(resource.SEARCH_FIELD_TITLE),
searchFields.Field(resource.SEARCH_FIELD_FOLDER), searchFields.Field(resource.SEARCH_FIELD_FOLDER),
searchFields.Field(resource.SEARCH_FIELD_TAGS), searchFields.Field(resource.SEARCH_FIELD_TAGS),
{ searchFields.Field(resource.SEARCH_FIELD_LEGACY_ID),
Name: unisearch.DASHBOARD_LEGACY_ID,
Type: resource.ResourceTableColumnDefinition_INT64,
Description: "Deprecated legacy id of the dashboard",
},
{ {
Name: "errors_last_30_days", Name: "errors_last_30_days",
Type: resource.ResourceTableColumnDefinition_INT64, Type: resource.ResourceTableColumnDefinition_INT64,

@ -57,7 +57,6 @@ import (
"github.com/grafana/grafana/pkg/setting" "github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/storage/legacysql/dualwrite" "github.com/grafana/grafana/pkg/storage/legacysql/dualwrite"
"github.com/grafana/grafana/pkg/storage/unified/resource" "github.com/grafana/grafana/pkg/storage/unified/resource"
"github.com/grafana/grafana/pkg/storage/unified/search"
"github.com/grafana/grafana/pkg/util" "github.com/grafana/grafana/pkg/util"
"github.com/grafana/grafana/pkg/util/retryer" "github.com/grafana/grafana/pkg/util/retryer"
"go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/attribute"
@ -1541,7 +1540,7 @@ func (dr *DashboardServiceImpl) FindDashboards(ctx context.Context, query *dashb
finalResults := make([]dashboards.DashboardSearchProjection, len(response.Hits)) finalResults := make([]dashboards.DashboardSearchProjection, len(response.Hits))
for i, hit := range response.Hits { for i, hit := range response.Hits {
result := dashboards.DashboardSearchProjection{ result := dashboards.DashboardSearchProjection{
ID: hit.Field.GetNestedInt64(search.DASHBOARD_LEGACY_ID), ID: hit.Field.GetNestedInt64(resource.SEARCH_FIELD_LEGACY_ID),
UID: hit.Name, UID: hit.Name,
OrgID: query.OrgId, OrgID: query.OrgId,
Title: hit.Title, Title: hit.Title,

@ -74,8 +74,8 @@ func TestParseResults(t *testing.T) {
Type: resource.ResourceTableColumnDefinition_INT32, Type: resource.ResourceTableColumnDefinition_INT32,
}, },
{ {
Name: search.DASHBOARD_LEGACY_ID, Name: resource.SEARCH_FIELD_LEGACY_ID,
Type: resource.ResourceTableColumnDefinition_INT32, Type: resource.ResourceTableColumnDefinition_INT64,
}, },
}, },
Rows: []*resource.ResourceTableRow{ Rows: []*resource.ResourceTableRow{

@ -28,7 +28,6 @@ import (
"github.com/grafana/grafana/pkg/services/search/model" "github.com/grafana/grafana/pkg/services/search/model"
"github.com/grafana/grafana/pkg/services/store/entity" "github.com/grafana/grafana/pkg/services/store/entity"
"github.com/grafana/grafana/pkg/storage/unified/resource" "github.com/grafana/grafana/pkg/storage/unified/resource"
"github.com/grafana/grafana/pkg/storage/unified/search"
"github.com/grafana/grafana/pkg/util" "github.com/grafana/grafana/pkg/util"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
) )
@ -219,7 +218,7 @@ func (s *Service) searchFoldersFromApiServer(ctx context.Context, query folder.S
for i, item := range parsedResults.Hits { for i, item := range parsedResults.Hits {
slug := slugify.Slugify(item.Title) slug := slugify.Slugify(item.Title)
hitList[i] = &model.Hit{ hitList[i] = &model.Hit{
ID: item.Field.GetNestedInt64(search.DASHBOARD_LEGACY_ID), ID: item.Field.GetNestedInt64(resource.SEARCH_FIELD_LEGACY_ID),
UID: item.Name, UID: item.Name,
OrgID: query.OrgID, OrgID: query.OrgID,
Title: item.Title, Title: item.Title,

@ -15,7 +15,6 @@ import (
claims "github.com/grafana/authlib/types" claims "github.com/grafana/authlib/types"
"github.com/grafana/grafana/pkg/apimachinery/utils" "github.com/grafana/grafana/pkg/apimachinery/utils"
"github.com/grafana/grafana/pkg/storage/unified/resource" "github.com/grafana/grafana/pkg/storage/unified/resource"
"github.com/grafana/grafana/pkg/storage/unified/search"
"github.com/grafana/grafana/pkg/apis/folder/v0alpha1" "github.com/grafana/grafana/pkg/apis/folder/v0alpha1"
"github.com/grafana/grafana/pkg/infra/log" "github.com/grafana/grafana/pkg/infra/log"
@ -238,7 +237,7 @@ func (ss *FolderUnifiedStoreImpl) GetChildren(ctx context.Context, q folder.GetC
} }
f := &folder.FolderReference{ f := &folder.FolderReference{
ID: item.Field.GetNestedInt64(search.DASHBOARD_LEGACY_ID), ID: item.Field.GetNestedInt64(resource.SEARCH_FIELD_LEGACY_ID),
UID: item.Name, UID: item.Name,
Title: item.Title, Title: item.Title,
ParentUID: item.Folder, ParentUID: item.Folder,

@ -272,7 +272,8 @@ func (x *searchableDocumentFields) Field(name string) *ResourceTableColumnDefini
} }
const SEARCH_FIELD_PREFIX = "fields." const SEARCH_FIELD_PREFIX = "fields."
const SEARCH_FIELD_ID = "_id" // {namespace}/{group}/{resource}/{name} const SEARCH_FIELD_ID = "_id" // {namespace}/{group}/{resource}/{name}
const SEARCH_FIELD_LEGACY_ID = utils.LabelKeyDeprecatedInternalID
const SEARCH_FIELD_KIND = "kind" // resource ( for federated index filtering ) const SEARCH_FIELD_KIND = "kind" // resource ( for federated index filtering )
const SEARCH_FIELD_GROUP_RESOURCE = "gr" // group/resource const SEARCH_FIELD_GROUP_RESOURCE = "gr" // group/resource
const SEARCH_FIELD_NAMESPACE = "namespace" const SEARCH_FIELD_NAMESPACE = "namespace"
@ -387,6 +388,11 @@ func StandardSearchFields() SearchableDocumentFields {
Type: ResourceTableColumnDefinition_DOUBLE, Type: ResourceTableColumnDefinition_DOUBLE,
Description: "The search score", Description: "The search score",
}, },
{
Name: SEARCH_FIELD_LEGACY_ID,
Type: ResourceTableColumnDefinition_INT64,
Description: "Deprecated legacy id of the resource",
},
}) })
if err != nil { if err != nil {
panic("failed to initialize standard search fields") panic("failed to initialize standard search fields")

@ -9,6 +9,7 @@ import (
"os" "os"
"path/filepath" "path/filepath"
"slices" "slices"
"strconv"
"strings" "strings"
"sync" "sync"
"time" "time"
@ -1029,6 +1030,15 @@ func (b *bleveIndex) hitsToTable(ctx context.Context, selectFields []string, hit
if match.Expl != nil { if match.Expl != nil {
row.Cells[i], err = json.Marshal(match.Expl) row.Cells[i], err = json.Marshal(match.Expl)
} }
case resource.SEARCH_FIELD_LEGACY_ID:
v := match.Fields[resource.SEARCH_FIELD_LABELS+"."+resource.SEARCH_FIELD_LEGACY_ID]
if v != nil {
str, ok := v.(string)
if ok {
id, _ := strconv.ParseInt(str, 10, 64)
row.Cells[i], err = encoders[i](id)
}
}
default: default:
fieldName := f.Name fieldName := f.Name
// since the bleve index fields mix common and resource-specific fields, it is possible a conflict can happen // since the bleve index fields mix common and resource-specific fields, it is possible a conflict can happen
@ -1060,6 +1070,7 @@ func getAllFields(standard resource.SearchableDocumentFields, custom resource.Se
standard.Field(resource.SEARCH_FIELD_FOLDER), standard.Field(resource.SEARCH_FIELD_FOLDER),
standard.Field(resource.SEARCH_FIELD_RV), standard.Field(resource.SEARCH_FIELD_RV),
standard.Field(resource.SEARCH_FIELD_CREATED), standard.Field(resource.SEARCH_FIELD_CREATED),
standard.Field(resource.SEARCH_FIELD_LEGACY_ID),
} }
if custom != nil { if custom != nil {

@ -348,6 +348,9 @@ func TestBleveBackend(t *testing.T) {
Checksum: "xxxx", Checksum: "xxxx",
TimestampMillis: 300, TimestampMillis: 300,
}, },
Labels: map[string]string{
utils.LabelKeyDeprecatedInternalID: "123",
},
}) })
_ = index.Write(&resource.IndexableDocument{ _ = index.Write(&resource.IndexableDocument{
RV: 2, RV: 2,
@ -359,7 +362,8 @@ func TestBleveBackend(t *testing.T) {
}, },
Title: "yyy (folder)", Title: "yyy (folder)",
Labels: map[string]string{ Labels: map[string]string{
"region": "west", "region": "west",
utils.LabelKeyDeprecatedInternalID: "321",
}, },
}) })
return rv, nil return rv, nil

@ -18,7 +18,6 @@ import (
// Standard dashboard fields // Standard dashboard fields
//------------------------------------------------------------ //------------------------------------------------------------
const DASHBOARD_LEGACY_ID = "legacy_id"
const DASHBOARD_SCHEMA_VERSION = "schema_version" const DASHBOARD_SCHEMA_VERSION = "schema_version"
const DASHBOARD_LINK_COUNT = "link_count" const DASHBOARD_LINK_COUNT = "link_count"
const DASHBOARD_PANEL_TYPES = "panel_types" const DASHBOARD_PANEL_TYPES = "panel_types"
@ -189,11 +188,6 @@ func DashboardBuilder(namespaced resource.NamespacedDocumentSupplier) (resource.
Filterable: true, Filterable: true,
}, },
}, },
{
Name: DASHBOARD_LEGACY_ID,
Type: resource.ResourceTableColumnDefinition_INT64,
Description: "Deprecated legacy id of the dashboard",
},
}) })
if namespaced == nil { if namespaced == nil {
namespaced = func(ctx context.Context, namespace string, blob resource.BlobSupport) (resource.DocumentBuilder, error) { namespaced = func(ctx context.Context, namespace string, blob resource.BlobSupport) (resource.DocumentBuilder, error) {
@ -314,9 +308,9 @@ func (s *DashboardDocumentBuilder) BuildDocument(ctx context.Context, key *resou
} }
doc.Fields = map[string]any{ doc.Fields = map[string]any{
DASHBOARD_SCHEMA_VERSION: summary.SchemaVersion, DASHBOARD_SCHEMA_VERSION: summary.SchemaVersion,
DASHBOARD_LINK_COUNT: summary.LinkCount, DASHBOARD_LINK_COUNT: summary.LinkCount,
DASHBOARD_LEGACY_ID: summary.ID, resource.SEARCH_FIELD_LEGACY_ID: summary.ID,
} }
if len(panelTypes) > 0 { if len(panelTypes) > 0 {
@ -342,7 +336,6 @@ func (s *DashboardDocumentBuilder) BuildDocument(ctx context.Context, key *resou
func DashboardFields() []string { func DashboardFields() []string {
baseFields := []string{ baseFields := []string{
DASHBOARD_LEGACY_ID,
DASHBOARD_SCHEMA_VERSION, DASHBOARD_SCHEMA_VERSION,
DASHBOARD_LINK_COUNT, DASHBOARD_LINK_COUNT,
DASHBOARD_PANEL_TYPES, DASHBOARD_PANEL_TYPES,

@ -31,7 +31,7 @@
], ],
"errors_last_1_days": 1, "errors_last_1_days": 1,
"errors_last_7_days": 1, "errors_last_7_days": 1,
"legacy_id": 141, "grafana.app/deprecatedInternalID": 141,
"link_count": 0, "link_count": 0,
"panel_types": [ "panel_types": [
"barchart", "barchart",

@ -43,6 +43,13 @@
"description": "created timestamp", "description": "created timestamp",
"priority": 0 "priority": 0
}, },
{
"name": "grafana.app/deprecatedInternalID",
"type": "number",
"format": "int64",
"description": "Deprecated legacy id of the resource",
"priority": 0
},
{ {
"name": "schema_version", "name": "schema_version",
"type": "number", "type": "number",
@ -168,13 +175,6 @@
"format": "int64", "format": "int64",
"description": "Total number of views", "description": "Total number of views",
"priority": 0 "priority": 0
},
{
"name": "legacy_id",
"type": "number",
"format": "int64",
"description": "Deprecated legacy id of the dashboard",
"priority": 0
} }
], ],
"rows": [ "rows": [
@ -228,6 +228,7 @@
"xxx", "xxx",
null, null,
null, null,
11,
null, null,
null, null,
[ [
@ -247,7 +248,6 @@
100, 100,
null, null,
null, null,
null,
null null
], ],
"object": { "object": {
@ -271,6 +271,7 @@
"xxx", "xxx",
null, null,
null, null,
10,
null, null,
null, null,
[ [
@ -291,7 +292,6 @@
50, 50,
null, null,
null, null,
null,
null null
], ],
"object": { "object": {

@ -42,6 +42,13 @@
"format": "int64", "format": "int64",
"description": "created timestamp", "description": "created timestamp",
"priority": 0 "priority": 0
},
{
"name": "grafana.app/deprecatedInternalID",
"type": "number",
"format": "int64",
"description": "Deprecated legacy id of the resource",
"priority": 0
} }
], ],
"rows": [ "rows": [
@ -52,7 +59,8 @@
null, null,
null, null,
null, null,
null null,
321
], ],
"object": { "object": {
"kind": "folders", "kind": "folders",
@ -71,7 +79,8 @@
null, null,
null, null,
null, null,
null null,
123
], ],
"object": { "object": {
"kind": "folders", "kind": "folders",

Loading…
Cancel
Save