diff --git a/internal/bootstrap/data/setting.go b/internal/bootstrap/data/setting.go index 9057b4f2..f6134884 100644 --- a/internal/bootstrap/data/setting.go +++ b/internal/bootstrap/data/setting.go @@ -143,7 +143,7 @@ func InitialSettings() []model.SettingItem { // single settings {Key: conf.Token, Value: token, Type: conf.TypeString, Group: model.SINGLE, Flag: model.PRIVATE}, - {Key: conf.SearchIndex, Value: "none", Type: conf.TypeSelect, Options: "database,bleve,none", Group: model.INDEX}, + {Key: conf.SearchIndex, Value: "none", Type: conf.TypeSelect, Options: "database,database_non_full_text,bleve,none", Group: model.INDEX}, {Key: conf.AutoUpdateIndex, Value: "false", Type: conf.TypeBool, Group: model.INDEX}, {Key: conf.IgnorePaths, Value: "", Type: conf.TypeText, Group: model.INDEX, Flag: model.PRIVATE, Help: `one path per line`}, {Key: conf.IndexProgress, Value: "{}", Type: conf.TypeText, Group: model.SINGLE, Flag: model.PRIVATE}, diff --git a/internal/db/searchnode.go b/internal/db/searchnode.go index c93185b5..909d6452 100644 --- a/internal/db/searchnode.go +++ b/internal/db/searchnode.go @@ -54,21 +54,23 @@ func GetSearchNodesByParent(parent string) ([]model.SearchNode, error) { return nodes, nil } -func SearchNode(req model.SearchReq) ([]model.SearchNode, int64, error) { +func SearchNode(req model.SearchReq, useFullText bool) ([]model.SearchNode, int64, error) { var searchDB *gorm.DB - switch conf.Conf.Database.Type { - case "sqlite3": + if !useFullText || conf.Conf.Database.Type == "sqlite3" { keywordsClause := db.Where("1 = 1") for _, keyword := range strings.Fields(req.Keywords) { keywordsClause = keywordsClause.Where("name LIKE ?", fmt.Sprintf("%%%s%%", keyword)) } searchDB = db.Model(&model.SearchNode{}).Where(whereInParent(req.Parent)).Where(keywordsClause) - case "mysql": - searchDB = db.Model(&model.SearchNode{}).Where(whereInParent(req.Parent)). - Where("MATCH (name) AGAINST (? IN BOOLEAN MODE)", "'*" + req.Keywords + "*'") - case "postgres": - searchDB = db.Model(&model.SearchNode{}).Where(whereInParent(req.Parent)). - Where("to_tsvector(name) @@ to_tsquery(?)", strings.Join(strings.Fields(req.Keywords), " & ")) + } else { + switch conf.Conf.Database.Type { + case "mysql": + searchDB = db.Model(&model.SearchNode{}).Where(whereInParent(req.Parent)). + Where("MATCH (name) AGAINST (? IN BOOLEAN MODE)", "'*"+req.Keywords+"*'") + case "postgres": + searchDB = db.Model(&model.SearchNode{}).Where(whereInParent(req.Parent)). + Where("to_tsvector(name) @@ to_tsquery(?)", strings.Join(strings.Fields(req.Keywords), " & ")) + } } var count int64 if err := searchDB.Count(&count).Error; err != nil { diff --git a/internal/search/db/search.go b/internal/search/db/search.go index f3de0750..b6613e3b 100644 --- a/internal/search/db/search.go +++ b/internal/search/db/search.go @@ -15,7 +15,7 @@ func (D DB) Config() searcher.Config { } func (D DB) Search(ctx context.Context, req model.SearchReq) ([]model.SearchNode, int64, error) { - return db.SearchNode(req) + return db.SearchNode(req, true) } func (D DB) Index(ctx context.Context, node model.SearchNode) error { diff --git a/internal/search/db_non_full_text/init.go b/internal/search/db_non_full_text/init.go new file mode 100644 index 00000000..9ac56fa3 --- /dev/null +++ b/internal/search/db_non_full_text/init.go @@ -0,0 +1,16 @@ +package db + +import ( + "github.com/alist-org/alist/v3/internal/search/searcher" +) + +var config = searcher.Config{ + Name: "database_non_full_text", + AutoUpdate: true, +} + +func init() { + searcher.RegisterSearcher(config, func() (searcher.Searcher, error) { + return &DB{}, nil + }) +} diff --git a/internal/search/db_non_full_text/search.go b/internal/search/db_non_full_text/search.go new file mode 100644 index 00000000..7c88c758 --- /dev/null +++ b/internal/search/db_non_full_text/search.go @@ -0,0 +1,45 @@ +package db + +import ( + "context" + + "github.com/alist-org/alist/v3/internal/db" + "github.com/alist-org/alist/v3/internal/model" + "github.com/alist-org/alist/v3/internal/search/searcher" +) + +type DB struct{} + +func (D DB) Config() searcher.Config { + return config +} + +func (D DB) Search(ctx context.Context, req model.SearchReq) ([]model.SearchNode, int64, error) { + return db.SearchNode(req, false) +} + +func (D DB) Index(ctx context.Context, node model.SearchNode) error { + return db.CreateSearchNode(&node) +} + +func (D DB) BatchIndex(ctx context.Context, nodes []model.SearchNode) error { + return db.BatchCreateSearchNodes(&nodes) +} + +func (D DB) Get(ctx context.Context, parent string) ([]model.SearchNode, error) { + return db.GetSearchNodesByParent(parent) +} + +func (D DB) Del(ctx context.Context, prefix string) error { + return db.DeleteSearchNodesByParent(prefix) +} + +func (D DB) Release(ctx context.Context) error { + return nil +} + +func (D DB) Clear(ctx context.Context) error { + return db.ClearSearchNodes() +} + +var _ searcher.Searcher = (*DB)(nil)