Files
kgpz_web/viewmodels/searchview.go
Simon Martens 44c7258a50 Suche (cont.)
2025-02-18 11:01:46 +01:00

165 lines
4.2 KiB
Go

package viewmodels
import (
"fmt"
"strings"
"sync"
"github.com/Theodor-Springmann-Stiftung/kgpz_web/helpers/datatypes"
searchprovider "github.com/Theodor-Springmann-Stiftung/kgpz_web/providers/search"
"github.com/Theodor-Springmann-Stiftung/kgpz_web/xmlmodels"
"github.com/blevesearch/bleve/v2"
"github.com/blevesearch/bleve/v2/search/query"
"golang.org/x/text/cases"
"golang.org/x/text/language"
"golang.org/x/text/unicode/norm"
)
type Result[T any] struct {
Count uint64
Items []T
}
type SearchView struct {
Agents Result[xmlmodels.Agent]
Works Result[xmlmodels.Work]
Places Result[xmlmodels.Place]
Categories Result[xmlmodels.Category]
Pieces Result[xmlmodels.Piece]
Issues Result[xmlmodels.Issue]
}
func NewSearchView(search string, kgpz *xmlmodels.Library, sp *searchprovider.SearchProvider) (*SearchView, error) {
sw := SearchView{}
search = datatypes.DeleteTags(search)
search = datatypes.NormalizeString(search)
search = datatypes.RemovePunctuation(search)
search = cases.Lower(language.German).String(search)
search = norm.NFKD.String(search)
searches := strings.Split(search, " ")
queries := make([]query.Query, 0, len(searches))
for _, s := range searches {
if strings.TrimSpace(s) == "" {
continue
}
queries = append(queries, bleve.NewTermQuery(s))
}
query := bleve.NewConjunctionQuery(queries...)
request := bleve.NewSearchRequest(query)
request.Size = 100
agentIndex, erragent := sp.GetIndex(xmlmodels.AGENT_TYPE)
workIndex, errwork := sp.GetIndex(xmlmodels.WORK_TYPE)
placeIndex, errplace := sp.GetIndex(xmlmodels.PLACE_TYPE)
categoryIndex, errcategory := sp.GetIndex(xmlmodels.CATEGORY_TYPE)
pieceIndex, errpiece := sp.GetIndex(xmlmodels.PIECE_TYPE)
issueIndex, errissue := sp.GetIndex(xmlmodels.ISSUE_TYPE)
if agentIndex == nil || workIndex == nil || placeIndex == nil || categoryIndex == nil || pieceIndex == nil || issueIndex == nil {
return nil, fmt.Errorf("Indeces not found.")
}
wg := sync.WaitGroup{}
if erragent == nil {
wg.Add(1)
go func() {
agentResults, _ := agentIndex.Search(request)
result := Result[xmlmodels.Agent]{Count: agentResults.Total}
for _, hit := range agentResults.Hits {
agent := kgpz.Agents.Item(hit.ID)
if agent != nil {
result.Items = append(result.Items, *agent)
}
}
sw.Agents = result
wg.Done()
}()
}
if errwork == nil {
wg.Add(1)
go func() {
workResults, _ := workIndex.Search(request)
result := Result[xmlmodels.Work]{Count: workResults.Total}
for _, hit := range workResults.Hits {
work := kgpz.Works.Item(hit.ID)
if work != nil {
result.Items = append(result.Items, *work)
}
}
sw.Works = result
wg.Done()
}()
}
if errplace == nil {
wg.Add(1)
go func() {
placeResults, _ := placeIndex.Search(request)
result := Result[xmlmodels.Place]{Count: placeResults.Total}
for _, hit := range placeResults.Hits {
place := kgpz.Places.Item(hit.ID)
if place != nil {
result.Items = append(result.Items, *place)
}
}
sw.Places = result
wg.Done()
}()
}
if errcategory == nil {
wg.Add(1)
go func() {
categoryResults, _ := categoryIndex.Search(request)
result := Result[xmlmodels.Category]{Count: categoryResults.Total}
for _, hit := range categoryResults.Hits {
category := kgpz.Categories.Item(hit.ID)
if category != nil {
result.Items = append(result.Items, *category)
}
}
sw.Categories = result
wg.Done()
}()
}
if errpiece == nil {
wg.Add(1)
go func() {
pieceResults, _ := pieceIndex.Search(request)
result := Result[xmlmodels.Piece]{Count: pieceResults.Total}
for _, hit := range pieceResults.Hits {
piece := kgpz.Pieces.Item(hit.ID)
if piece != nil {
result.Items = append(result.Items, *piece)
}
}
sw.Pieces = result
wg.Done()
}()
}
if errissue == nil {
wg.Add(1)
go func() {
issueResults, _ := issueIndex.Search(request)
result := Result[xmlmodels.Issue]{Count: issueResults.Total}
for _, hit := range issueResults.Hits {
issue := kgpz.Issues.Item(hit.ID)
if issue != nil {
result.Items = append(result.Items, *issue)
}
}
sw.Issues = result
wg.Done()
}()
}
wg.Wait()
return &sw, nil
}