112 lines
2.1 KiB
Go
112 lines
2.1 KiB
Go
// Copyright (C) 2017 Marius Schellenberger
|
|
|
|
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
|
|
"github.com/blevesearch/bleve"
|
|
"github.com/blevesearch/bleve/document"
|
|
)
|
|
|
|
type IndexPage struct {
|
|
Title string `json:"title"`
|
|
Search string `json:"search"`
|
|
}
|
|
|
|
func indexErr(i interface{}) error {
|
|
return fmt.Errorf("index: %s", i)
|
|
}
|
|
|
|
type Index struct {
|
|
i bleve.Index
|
|
}
|
|
|
|
func NewIndex(path string) (i *Index, err error) {
|
|
var bi bleve.Index
|
|
if _, err = os.Stat(path); os.IsNotExist(err) {
|
|
mapping := bleve.NewIndexMapping()
|
|
bi, err = bleve.New(path, mapping)
|
|
if err != nil {
|
|
err = indexErr(err)
|
|
return
|
|
}
|
|
i = &Index{index: bi}
|
|
_, err = i.Index(indexName, welcome, defUser, true)
|
|
if err != nil {
|
|
err = indexErr(err)
|
|
return
|
|
}
|
|
} else {
|
|
bi, err = bleve.Open(path)
|
|
if err != nil {
|
|
err = indexErr(err)
|
|
return
|
|
}
|
|
i = &Index{index: bi}
|
|
}
|
|
i.cache = NewIndexCache()
|
|
return
|
|
}
|
|
|
|
func NewDumpIndex(path string) (i *Index, err error) {
|
|
bi, err := bleve.OpenUsing(path, map[string]interface{}{"read_only": true})
|
|
if err != nil {
|
|
err = indexErr(err)
|
|
return
|
|
}
|
|
i = &Index{index: bi}
|
|
return
|
|
}
|
|
|
|
func (i *Index) Close() error {
|
|
return i.i.Close()
|
|
}
|
|
|
|
func (i *Index) Add(ip IndexPage) error {
|
|
doc, _ := i.i.Document(ip.Title)
|
|
if doc != nil {
|
|
err := i.Delete(ip.Title)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return i.i.Index(ip.Title, ip)
|
|
}
|
|
|
|
func (i *Index) Delete(title string) error {
|
|
return i.i.Delete(title)
|
|
}
|
|
|
|
type Result struct {
|
|
Title string
|
|
Text string
|
|
}
|
|
|
|
func (i *Index) Search(search string) (results []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
|
|
}
|
|
title := hit.ID
|
|
text := ""
|
|
for fragField, frags := range hit.Fragments {
|
|
if fragField == "title" || fragField == "search" {
|
|
for _, f := range frags {
|
|
text += f
|
|
}
|
|
break
|
|
}
|
|
}
|
|
results = append(results, Result{title, text})
|
|
}
|
|
return
|
|
}
|