Select Git revision
collection.go
search.go 2.22 KiB
package search
import (
"strings"
"git.perx.ru/perxis/perxis-go/pkg/errors"
"git.perx.ru/perxis/perxis-go/pkg/items"
bleve "github.com/blevesearch/bleve/v2"
)
func ItemTextSearch(query string, item *items.Item) (*items.Item, []string, error) {
index, err := bleve.NewMemOnly(bleve.NewIndexMapping())
if err != nil {
return nil, nil, err
}
if err = index.Index(item.ID, item); err != nil {
return nil, nil, err
}
searchRequest := bleve.NewSearchRequest(bleve.NewQueryStringQuery(query))
searchRequest.Highlight = bleve.NewHighlight()
searchResult, err := index.Search(searchRequest)
if err != nil {
return nil, nil, err
}
if searchResult.Total == 0 {
return nil, nil, errors.New("no results found")
}
hint := searchResult.Hits[0]
if hint.ID != item.ID {
return nil, nil, errors.New("search result not match item")
}
fields := make([]string, 0, len(hint.Fragments))
for key, value := range hint.Fragments {
key = strings.TrimPrefix(key, "data.")
if key == "id" {
item.Data[key] = value
}
if err = item.Set(key, value); err != nil {
return nil, nil, err
}
fields = append(fields, key)
}
return item, fields, nil
}
func ItemsTextSearch(query string, itms []*items.Item) ([]*items.Item, error) {
index, err := bleve.NewMemOnly(bleve.NewIndexMapping())
if err != nil {
return nil, err
}
im := make(map[string]*items.Item, len(itms))
for _, i := range itms {
im[i.ID] = i
if err = index.Index(i.ID, i); err != nil {
return nil, err
}
}
searchRequest := bleve.NewSearchRequest(bleve.NewQueryStringQuery(query))
searchRequest.Highlight = bleve.NewHighlight()
searchResult, err := index.Search(searchRequest)
if err != nil {
return nil, err
}
if searchResult.Total == 0 {
return nil, errors.New("no results found")
}
result := make([]*items.Item, 0, len(searchResult.Hits))
for _, hint := range searchResult.Hits {
item, ok := im[hint.ID]
if !ok {
return nil, errors.New("search result not match item")
}
for key, value := range hint.Fragments {
key = strings.TrimPrefix(key, "data.")
if key == "id" {
item.Data[key] = value
}
if err = item.Set(key, value); err != nil {
return nil, err
}
}
result = append(result, item)
}
return result, nil
}