Skip to content

Commit

Permalink
search/bleve: add a query analyzer
Browse files Browse the repository at this point in the history
also add a SearchError type to convey error messages back to the client
  • Loading branch information
Wessie committed Jun 26, 2024
1 parent b2aa9db commit df79645
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 10 deletions.
30 changes: 23 additions & 7 deletions search/bleve/analyzer.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (
"github.com/blevesearch/bleve/v2/analysis/lang/cjk"
"github.com/blevesearch/bleve/v2/analysis/token/lowercase"
"github.com/blevesearch/bleve/v2/analysis/token/ngram"
"github.com/blevesearch/bleve/v2/analysis/token/porter"
"github.com/blevesearch/bleve/v2/analysis/token/unicodenorm"
"github.com/blevesearch/bleve/v2/registry"
"github.com/robpike/nihongo"
Expand All @@ -31,12 +30,6 @@ func AnalyzerConstructor(config map[string]interface{}, cache *registry.Cache) (
}
_ = cjkFilter

porterFilter, err := cache.TokenFilterNamed(porter.Name)
if err != nil {
return nil, err
}
_ = porterFilter

toLowerFilter, err := cache.TokenFilterNamed(lowercase.Name)
if err != nil {
return nil, err
Expand All @@ -56,8 +49,31 @@ func AnalyzerConstructor(config map[string]interface{}, cache *registry.Cache) (
return &rv, nil
}

func QueryAnalyzerConstructor(config map[string]any, cache *registry.Cache) (analysis.Analyzer, error) {
tokenizer, err := cache.TokenizerNamed(web.Name)
if err != nil {
return nil, err
}

toLowerFilter, err := cache.TokenFilterNamed(lowercase.Name)
if err != nil {
return nil, err
}

rv := analysis.DefaultAnalyzer{
Tokenizer: tokenizer,
TokenFilters: []analysis.TokenFilter{
FilterFn(RomajiFilter),
toLowerFilter,
},
}

return &rv, nil
}

func init() {
registry.RegisterAnalyzer("radio", AnalyzerConstructor)
registry.RegisterAnalyzer("radio-query", QueryAnalyzerConstructor)
}

type FilterFn func(input analysis.TokenStream) analysis.TokenStream
Expand Down
11 changes: 9 additions & 2 deletions search/bleve/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,14 @@ type Client struct {
hc *http.Client
}

type SearchError struct {
Err string
}

func (se *SearchError) Error() string {
return se.Err
}

var _ radio.SearchService = &Client{}

func (c *Client) Search(ctx context.Context, query string, limit int64, offset int64) (*radio.SearchResult, error) {
Expand All @@ -47,8 +55,7 @@ func (c *Client) Search(ctx context.Context, query string, limit int64, offset i
return nil, errors.E(op, err)
}
if resp.StatusCode != http.StatusOK {
// TODO: report actual error
return nil, errors.E(op, err)
return nil, errors.E(op, decodeError(resp.Body))
}

result := new(bleve.SearchResult)
Expand Down
2 changes: 1 addition & 1 deletion search/bleve/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ func constructIndexMapping() (mapping.IndexMapping, error) {
// create a mapping for our radio.Song type
sm := bleve.NewDocumentStaticMapping()
sm.StructTagKey = "bleve"
sm.DefaultAnalyzer = "radio"
sm.DefaultAnalyzer = "radio-query"

title := mixedTextMapping()
sm.AddFieldMappingsAt("title", title)
Expand Down
41 changes: 41 additions & 0 deletions search/bleve/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ func SearchHandler(idx *index) http.HandlerFunc {
err = errors.E(op, err)
hlog.FromRequest(r).Error().Err(err).Msg("failed to search")
w.WriteHeader(http.StatusInternalServerError)
_ = encodeError(w, err)
return
}

Expand All @@ -178,6 +179,10 @@ func SearchJSONHandler(idx *index) http.HandlerFunc {
if err != nil {
err = errors.E(op, err)
hlog.FromRequest(r).Error().Err(err).Msg("failed to search")
w.WriteHeader(http.StatusInternalServerError)
_ = json.NewEncoder(w).Encode(&SearchError{
Err: err.Error(),
})
return
}

Expand Down Expand Up @@ -216,6 +221,42 @@ func decodeResult(src io.Reader, result *bleve.SearchResult) error {
return nil
}

func encodeError(dst io.Writer, err error) error {
const op errors.Op = "search/bleve.encodeError"

var errString = "<nil>"
if err != nil {
errString = err.Error()
}

se := &SearchError{
Err: errString,
}

enc := _cache.enc.Get()
enc.Reset(dst)
defer _cache.enc.Put(enc)
if err := enc.Encode(se); err != nil {
return errors.E(op, err)
}
return nil
}

func decodeError(src io.Reader) *SearchError {
const op errors.Op = "search/bleve.decodeError"
var se SearchError

dec := _cache.dec.Get()
dec.Reset(src)
defer _cache.dec.Put(dec)
if err := dec.Decode(&se); err != nil {
return &SearchError{
Err: errors.E(op, err).Error(),
}
}
return &se
}

func bleveToRadio(result *bleve.SearchResult) (*radio.SearchResult, error) {
const op errors.Op = "search/bleve.bleveToRadio"

Expand Down

0 comments on commit df79645

Please sign in to comment.