103 lines
2.1 KiB
Go
103 lines
2.1 KiB
Go
// Copyright (C) 2018 Marius Schellenberger
|
|
|
|
package index
|
|
|
|
import (
|
|
"errors"
|
|
"git.giftfish.de/ston1th/godrop/v2"
|
|
"git.giftfish.de/ston1th/gowiki/pkg/core"
|
|
"github.com/blevesearch/bleve"
|
|
"html/template"
|
|
"os"
|
|
)
|
|
|
|
const maxSearchResult = 101
|
|
|
|
type indexPage struct {
|
|
Title string `json:"title"`
|
|
StoreTitle string `json:"store_title"`
|
|
Search string `json:"search"`
|
|
}
|
|
|
|
type Index struct {
|
|
i bleve.Index
|
|
}
|
|
|
|
func NewIndex(path string) (i *Index, err error) {
|
|
var bi bleve.Index
|
|
err = godrop.Unveil(path, "rwc")
|
|
if err != nil {
|
|
return
|
|
}
|
|
if _, err = os.Stat(path); os.IsNotExist(err) {
|
|
mapping := bleve.NewIndexMapping()
|
|
bi, err = bleve.New(path, mapping)
|
|
if err != nil {
|
|
err = errors.New("index: " + err.Error())
|
|
return
|
|
}
|
|
} else {
|
|
bi, err = bleve.Open(path)
|
|
if err != nil {
|
|
err = errors.New("index: " + err.Error())
|
|
return
|
|
}
|
|
}
|
|
i = &Index{i: bi}
|
|
return
|
|
}
|
|
|
|
func (i *Index) Close() error {
|
|
return i.i.Close()
|
|
}
|
|
|
|
func (i *Index) Add(title, storeTitle, search string) error {
|
|
doc, _ := i.i.Document(storeTitle)
|
|
if doc != nil {
|
|
err := i.Delete(storeTitle)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return i.i.Index(storeTitle, indexPage{title, storeTitle, search})
|
|
}
|
|
|
|
func (i *Index) Delete(storeTitle string) error {
|
|
return i.i.Delete(storeTitle)
|
|
}
|
|
|
|
func (i *Index) Search(search string) (results []core.Result, err error) {
|
|
req := bleve.NewSearchRequest(bleve.NewQueryStringQuery("title:" + search + " search:" + search))
|
|
req.Highlight = bleve.NewHighlightWithStyle("html")
|
|
req.Size = maxSearchResult
|
|
res, err := i.i.Search(req)
|
|
if err != nil {
|
|
return
|
|
}
|
|
for _, hit := range res.Hits {
|
|
if hit == nil {
|
|
continue
|
|
}
|
|
r := core.Result{StoreTitle: hit.ID}
|
|
d, err := i.i.Document(hit.ID)
|
|
if d == nil || err != nil {
|
|
continue
|
|
}
|
|
for _, v := range d.Fields {
|
|
if v.Name() == "title" {
|
|
r.Title = string(v.Value())
|
|
break
|
|
}
|
|
}
|
|
for fragField, frags := range hit.Fragments {
|
|
if fragField == "title" || fragField == "search" {
|
|
for _, f := range frags {
|
|
r.HTML += template.HTML(f)
|
|
}
|
|
break
|
|
}
|
|
}
|
|
results = append(results, r)
|
|
}
|
|
return
|
|
}
|