From 5ac6355e97f30e2bbefd27181505aeb9201c0ebb Mon Sep 17 00:00:00 2001 From: toshski <104477758+toshski@users.noreply.github.com> Date: Sat, 25 Jun 2022 04:03:55 +1200 Subject: [PATCH] feat: Create separate searchable fields for id, title, cast, site & description (#760) * Change search from one string of id, title, synopsis and cast to seperate search fields * Use the Simple Analyzer for Title and Search indexes * Fix whitespace formating --- pkg/api/scenes.go | 2 +- pkg/migrations/migrations.go | 14 ++++++++++++++ pkg/models/model_scene.go | 4 ++-- pkg/tasks/search.go | 25 +++++++++++++++++++++++-- 4 files changed, 40 insertions(+), 5 deletions(-) diff --git a/pkg/api/scenes.go b/pkg/api/scenes.go index b1040c718..b9f339aff 100644 --- a/pkg/api/scenes.go +++ b/pkg/api/scenes.go @@ -376,7 +376,7 @@ func (i SceneResource) searchSceneIndex(req *restful.Request, resp *restful.Resp query := bleve.NewQueryStringQuery(q) searchRequest := bleve.NewSearchRequest(query) - searchRequest.Fields = []string{"fulltext"} + searchRequest.Fields = []string{"Id", "title", "cast", "site", "description"} searchRequest.IncludeLocations = true searchRequest.From = 0 searchRequest.Size = 25 diff --git a/pkg/migrations/migrations.go b/pkg/migrations/migrations.go index b9a133184..e7dc46667 100644 --- a/pkg/migrations/migrations.go +++ b/pkg/migrations/migrations.go @@ -784,6 +784,20 @@ func Migrate() { return nil }, }, + { + // rebuild search indexes with new fields + ID: "034-rebuild-new-indexes", + Migrate: func(d *gorm.DB) error { + os.RemoveAll(common.IndexDirV2) + os.MkdirAll(common.IndexDirV2, os.ModePerm) + // rebuild asynchronously, no need to hold up startup, blocking the UI + go func() { + tasks.SearchIndex() + tasks.CalculateCacheSizes() + }() + return nil + }, + }, }) if err := m.Migrate(); err != nil { diff --git a/pkg/models/model_scene.go b/pkg/models/model_scene.go index aabca719d..dd895256e 100644 --- a/pkg/models/model_scene.go +++ b/pkg/models/model_scene.go @@ -93,8 +93,8 @@ type Scene struct { NeedsUpdate bool `json:"needs_update"` - Fulltext string `gorm:"-" json:"fulltext"` - Score float64 `gorm:"-" json:"_score"` + Description string `gorm:"-" json:"description"` + Score float64 `gorm:"-" json:"_score"` } type Image struct { diff --git a/pkg/tasks/search.go b/pkg/tasks/search.go index b6ebcaa7c..9f89f262e 100644 --- a/pkg/tasks/search.go +++ b/pkg/tasks/search.go @@ -6,6 +6,7 @@ import ( "strings" "github.com/blevesearch/bleve" + "github.com/blevesearch/bleve/analysis/analyzer/simple" "github.com/blevesearch/bleve/index/scorch" "github.com/sirupsen/logrus" "github.com/xbapps/xbvr/pkg/common" @@ -17,7 +18,11 @@ type Index struct { } type SceneIndexed struct { - Fulltext string `json:"fulltext"` + Description string `json:"description"` + Title string `json:"title"` + Cast string `json:"cast"` + Site string `json:"site"` + Id string `json:"id"` } func NewIndex(name string) (*Index, error) { @@ -25,7 +30,19 @@ func NewIndex(name string) (*Index, error) { path := filepath.Join(common.IndexDirV2, name) + // the simple analyzer is more approriate for the title and cast + // note this does not effect search unless the query includes cast: or title: + titleFieldMapping := bleve.NewTextFieldMapping() + titleFieldMapping.Analyzer = simple.Name + castFieldMapping := bleve.NewTextFieldMapping() + castFieldMapping.Analyzer = simple.Name + sceneMapping := bleve.NewDocumentMapping() + sceneMapping.AddFieldMappingsAt("title", titleFieldMapping) + sceneMapping.AddFieldMappingsAt("cast", castFieldMapping) + mapping := bleve.NewIndexMapping() + mapping.AddDocumentMapping("_default", sceneMapping) + idx, err := bleve.NewUsing(path, mapping, scorch.Name, scorch.Name, nil) if err != nil && err == bleve.ErrorIndexPathExists { idx, err = bleve.Open(path) @@ -55,7 +72,11 @@ func (i *Index) PutScene(scene models.Scene) error { } si := SceneIndexed{ - Fulltext: fmt.Sprintf("%v %v %v %v %v %v", scene.SceneID, scene.Title, scene.Site, scene.Synopsis, cast, castConcat), + Title: fmt.Sprintf("%v", scene.Title), + Description: fmt.Sprintf("%v", scene.Synopsis), + Cast: fmt.Sprintf("%v %v", cast, castConcat), + Site: fmt.Sprintf("%v", scene.Site), + Id: fmt.Sprintf("%v", scene.SceneID), } if err := i.Bleve.Index(scene.SceneID, si); err != nil { return err