package internal import ( "fmt" "path/filepath" "github.com/blevesearch/bleve/v2" log "github.com/sirupsen/logrus" ) type Indexer interface { Index(entry *Entry) error Size() int64 Search(q string, p int) (*bleve.SearchResult, error) } type indexer struct { conf *Config idx bleve.Index } func NewIndexer(conf *Config) (Indexer, error) { var ( idx bleve.Index err error ) fn := filepath.Join(conf.Data, "spyda.bleve") if FileExists(fn) { idx, err = bleve.Open(fn) } else { mapping := bleve.NewIndexMapping() idx, err = bleve.New(fn, mapping) } if err != nil { log.WithError(err).Error("error creating indexer") return nil, err } return &indexer{conf: conf, idx: idx}, nil } func (i *indexer) Size() int64 { count, err := i.idx.DocCount() if err != nil { log.WithError(err).Warn("error getting index size") return 0 } return int64(count) } func (i *indexer) Index(entry *Entry) error { return i.idx.Index(entry.Hash(), entry) } func (i *indexer) Search(q string, p int) (*bleve.SearchResult, error) { query := bleve.NewMatchQuery(q) searchRequest := bleve.NewSearchRequest(query) searchRequest.Fields = []string{"URL", "Title", "Author", "Summary", "Length"} searchRequest.Highlight = bleve.NewHighlight() searchRequest.Size = i.conf.ResultsPerPage searchRequest.From = searchRequest.Size * (p - 1) searchResults, err := i.idx.Search(searchRequest) if err != nil { log.WithError(err).Error("error searching index") return nil, fmt.Errorf("error searching index: %w", err) } return searchResults, nil }