2018-05-31 21:24:59 +00:00
|
|
|
package bleve
|
|
|
|
|
|
|
|
import (
|
|
|
|
"github.com/blevesearch/bleve"
|
|
|
|
"github.com/blevesearch/bleve/analysis/analyzer/keyword"
|
|
|
|
|
|
|
|
"github.com/khlieng/dispatch/storage"
|
|
|
|
)
|
|
|
|
|
|
|
|
// Bleve implements storage.MessageSearchProvider
|
|
|
|
type Bleve struct {
|
|
|
|
index bleve.Index
|
|
|
|
}
|
|
|
|
|
|
|
|
func New(path string) (*Bleve, error) {
|
|
|
|
index, err := bleve.Open(path)
|
|
|
|
if err == bleve.ErrorIndexPathDoesNotExist {
|
|
|
|
keywordMapping := bleve.NewTextFieldMapping()
|
|
|
|
keywordMapping.Analyzer = keyword.Name
|
|
|
|
keywordMapping.Store = false
|
|
|
|
keywordMapping.IncludeTermVectors = false
|
|
|
|
keywordMapping.IncludeInAll = false
|
|
|
|
|
|
|
|
contentMapping := bleve.NewTextFieldMapping()
|
|
|
|
contentMapping.Analyzer = "en"
|
|
|
|
contentMapping.Store = false
|
|
|
|
contentMapping.IncludeTermVectors = false
|
|
|
|
contentMapping.IncludeInAll = false
|
|
|
|
|
|
|
|
messageMapping := bleve.NewDocumentMapping()
|
|
|
|
messageMapping.StructTagKey = "bleve"
|
|
|
|
messageMapping.AddFieldMappingsAt("server", keywordMapping)
|
|
|
|
messageMapping.AddFieldMappingsAt("to", keywordMapping)
|
|
|
|
messageMapping.AddFieldMappingsAt("content", contentMapping)
|
|
|
|
|
|
|
|
mapping := bleve.NewIndexMapping()
|
|
|
|
mapping.AddDocumentMapping("message", messageMapping)
|
|
|
|
|
|
|
|
index, err = bleve.New(path, mapping)
|
|
|
|
}
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
return &Bleve{index: index}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (b *Bleve) Index(id string, message *storage.Message) error {
|
|
|
|
return b.index.Index(id, message)
|
|
|
|
}
|
|
|
|
|
2020-06-15 08:58:51 +00:00
|
|
|
func (b *Bleve) SearchMessages(network, channel, q string) ([]string, error) {
|
|
|
|
serverQuery := bleve.NewMatchQuery(network)
|
2018-05-31 21:24:59 +00:00
|
|
|
serverQuery.SetField("server")
|
|
|
|
channelQuery := bleve.NewMatchQuery(channel)
|
|
|
|
channelQuery.SetField("to")
|
|
|
|
contentQuery := bleve.NewMatchQuery(q)
|
|
|
|
contentQuery.SetField("content")
|
|
|
|
contentQuery.SetFuzziness(2)
|
|
|
|
|
|
|
|
query := bleve.NewBooleanQuery()
|
|
|
|
query.AddMust(serverQuery, channelQuery, contentQuery)
|
|
|
|
|
|
|
|
search := bleve.NewSearchRequest(query)
|
|
|
|
searchResults, err := b.index.Search(search)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
ids := make([]string, len(searchResults.Hits))
|
|
|
|
for i, hit := range searchResults.Hits {
|
|
|
|
ids[i] = hit.ID
|
|
|
|
}
|
|
|
|
|
|
|
|
return ids, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (b *Bleve) Close() {
|
|
|
|
b.index.Close()
|
|
|
|
}
|