* ✨ feat(search): search all feature - add Description field to Gist struct and index it - extend SearchGistMetadata with Description and Content - update Bleve and Meilisearch to index and search Description - modify ParseSearchQueryStr to parse description: and content: keywords - update templates and i18n for new search options * Fix test * Set content by default Signed-off-by: Thomas Miceli <tho.miceli@gmail.com> * Config to define default searchable fields Signed-off-by: Thomas Miceli <tho.miceli@gmail.com> --------- Signed-off-by: Thomas Miceli <tho.miceli@gmail.com> Co-authored-by: Thomas Miceli <tho.miceli@gmail.com>
158 lines
3.1 KiB
Go
158 lines
3.1 KiB
Go
package index
|
|
|
|
import (
|
|
"fmt"
|
|
"path/filepath"
|
|
"sync/atomic"
|
|
|
|
"github.com/rs/zerolog/log"
|
|
"github.com/thomiceli/opengist/internal/config"
|
|
)
|
|
|
|
var atomicIndexer atomic.Pointer[Indexer]
|
|
|
|
type Indexer interface {
|
|
Init() error
|
|
Close()
|
|
Reset() error
|
|
Add(gist *Gist) error
|
|
Remove(gistID uint) error
|
|
Search(metadata SearchGistMetadata, userId uint, page int) ([]uint, uint64, map[string]int, error)
|
|
}
|
|
|
|
type IndexerType string
|
|
|
|
const (
|
|
Bleve IndexerType = "bleve"
|
|
Meilisearch IndexerType = "meilisearch"
|
|
None IndexerType = ""
|
|
)
|
|
|
|
func IndexType() IndexerType {
|
|
switch config.C.Index {
|
|
case "bleve":
|
|
return Bleve
|
|
case "meilisearch":
|
|
return Meilisearch
|
|
default:
|
|
return None
|
|
}
|
|
}
|
|
|
|
func IndexEnabled() bool {
|
|
switch config.C.Index {
|
|
case "bleve", "meilisearch":
|
|
return true
|
|
default:
|
|
return false
|
|
}
|
|
}
|
|
|
|
func NewIndexer(idxType IndexerType) {
|
|
if !IndexEnabled() {
|
|
return
|
|
}
|
|
atomicIndexer.Store(nil)
|
|
|
|
var idx Indexer
|
|
|
|
switch idxType {
|
|
case Bleve:
|
|
idx = NewBleveIndexer(filepath.Join(config.GetHomeDir(), "opengist.index"))
|
|
case Meilisearch:
|
|
idx = NewMeiliIndexer(config.C.MeiliHost, config.C.MeiliAPIKey, "opengist")
|
|
default:
|
|
log.Warn().Msgf("Failed to create indexer, unknown indexer type: %s", idxType)
|
|
return
|
|
}
|
|
|
|
if err := idx.Init(); err != nil {
|
|
return
|
|
}
|
|
atomicIndexer.Store(&idx)
|
|
}
|
|
|
|
func Close() {
|
|
if !IndexEnabled() {
|
|
return
|
|
}
|
|
|
|
idx := atomicIndexer.Load()
|
|
if idx == nil {
|
|
return
|
|
}
|
|
|
|
(*idx).Close()
|
|
atomicIndexer.Store(nil)
|
|
}
|
|
|
|
func ResetIndex() error {
|
|
if !IndexEnabled() {
|
|
return nil
|
|
}
|
|
|
|
idx := atomicIndexer.Load()
|
|
if idx == nil {
|
|
return fmt.Errorf("indexer is not initialized")
|
|
}
|
|
|
|
return (*idx).Reset()
|
|
}
|
|
|
|
func AddInIndex(gist *Gist) error {
|
|
if !IndexEnabled() {
|
|
return nil
|
|
}
|
|
|
|
idx := atomicIndexer.Load()
|
|
if idx == nil {
|
|
return fmt.Errorf("indexer is not initialized")
|
|
}
|
|
|
|
return (*idx).Add(gist)
|
|
}
|
|
|
|
func RemoveFromIndex(gistID uint) error {
|
|
if !IndexEnabled() {
|
|
return nil
|
|
}
|
|
|
|
idx := atomicIndexer.Load()
|
|
if idx == nil {
|
|
return fmt.Errorf("indexer is not initialized")
|
|
}
|
|
|
|
return (*idx).Remove(gistID)
|
|
}
|
|
|
|
// SearchGists returns a list of Gist IDs that match the given search metadata.
|
|
// If the indexer is not enabled, it returns nil, 0, nil, nil.
|
|
// If the indexer is not initialized, it returns nil, 0, nil, fmt.Errorf("indexer is not initialized").
|
|
// The function returns an error if any.
|
|
func SearchGists(metadata SearchGistMetadata, userId uint, page int) ([]uint, uint64, map[string]int, error) {
|
|
if !IndexEnabled() {
|
|
return nil, 0, nil, nil
|
|
}
|
|
|
|
idx := atomicIndexer.Load()
|
|
if idx == nil {
|
|
return nil, 0, nil, fmt.Errorf("indexer is not initialized")
|
|
}
|
|
|
|
return (*idx).Search(metadata, userId, page)
|
|
}
|
|
|
|
func DepreactionIndexDirname() {
|
|
if config.C.IndexEnabled {
|
|
log.Warn().Msg("The 'index.enabled'/'OG_INDEX_ENABLED' configuration option is deprecated and will be removed in a future version. Please use 'index'/'OG_INDEX' instead.")
|
|
}
|
|
|
|
if config.C.Index == "" {
|
|
config.C.Index = "bleve"
|
|
}
|
|
|
|
if config.C.BleveDirname != "" {
|
|
log.Warn().Msg("The 'index.dirname'/'OG_INDEX_DIRNAME' configuration option is deprecated and will be removed in a future version.")
|
|
}
|
|
}
|