// 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" "github.com/blevesearch/bleve/mapping" "html/template" "os" "strings" "time" ) const maxSearchResult = 101 const docType = "document" type document struct { Text string `json:"text"` Keyword []string `json:"keyword"` Created time.Time `json:"created"` } func (d *document) Type() string { return docType } 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) { var m *mapping.IndexMappingImpl m, err = createMapping() //m := bleve.NewIndexMapping() bi, err = bleve.New(path, m) 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 string) (id string, err error) { id = newID() for { doc, _ := i.i.Document(id) if doc == nil { break } id = newID() } k := classify(text) err = i.i.Index(id, &document{text, k, time.Now()}) return } func (i *Index) Delete(id string) error { return i.i.Delete(id) } func (i *Index) Search(search string) (results core.Results, 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 == "keyword" { var k string for _, f := range frags { k += f } r.Keyword = strings.ReplaceAll(strings.ReplaceAll(k, "", ""), "", "") } if fragField == "text" || fragField == "created" { for _, f := range frags { r.HTML += template.HTML(f) } break } } results = append(results, r) } return }