mirror of
https://github.com/Theodor-Springmann-Stiftung/kgpz_web.git
synced 2025-10-28 16:45:32 +00:00
165 lines
4.2 KiB
Go
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
|
|
}
|