99 lines
1.9 KiB
Go
99 lines
1.9 KiB
Go
// Copyright (C) 2019 Marius Schellenberger
|
|
|
|
package index
|
|
|
|
import (
|
|
"errors"
|
|
"git.giftfish.de/ston1th/docstore/pkg/core"
|
|
"git.giftfish.de/ston1th/godrop/v2"
|
|
"github.com/blevesearch/bleve"
|
|
"html/template"
|
|
"os"
|
|
)
|
|
|
|
const maxSearchResult = 101
|
|
|
|
type indexDocument struct {
|
|
Text string `json:"text"`
|
|
Date string `json:"date"`
|
|
Type string `json:"type"`
|
|
}
|
|
|
|
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(text, docType string) (id string, err error) {
|
|
id = newID()
|
|
for {
|
|
doc, _ := i.i.Document(id)
|
|
if doc == nil {
|
|
break
|
|
}
|
|
id = newID()
|
|
}
|
|
err = i.i.Index(id, indexDocument{text, core.Now(), docType})
|
|
return
|
|
}
|
|
|
|
func (i *Index) Delete(id string) error {
|
|
return i.i.Delete(id)
|
|
}
|
|
|
|
func (i *Index) Search(search string) (results []core.Result, err error) {
|
|
req := bleve.NewSearchRequest(bleve.NewQueryStringQuery(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{ID: hit.ID}
|
|
d, err := i.i.Document(hit.ID)
|
|
if d == nil || err != nil {
|
|
continue
|
|
}
|
|
for fragField, frags := range hit.Fragments {
|
|
if fragField == "text" || fragField == "type" || fragField == "date" {
|
|
for _, f := range frags {
|
|
r.HTML += template.HTML(f)
|
|
}
|
|
break
|
|
}
|
|
}
|
|
results = append(results, r)
|
|
}
|
|
return
|
|
}
|