@@ -26,18 +26,9 @@ func (b *Bleve) Config() searcher.Config {
2626}
2727
2828func (b * Bleve ) Search (ctx context.Context , req model.SearchReq ) ([]model.SearchNode , int64 , error ) {
29- var queries []query2.Query
30- query := bleve .NewMatchQuery (req .Keywords )
31- query .SetField ("name" )
32- queries = append (queries , query )
33- if req .Scope != 0 {
34- isDir := req .Scope == 1
35- isDirQuery := bleve .NewBoolFieldQuery (isDir )
36- queries = append (queries , isDirQuery )
37- }
38- reqQuery := bleve .NewConjunctionQuery (queries ... )
29+ reqQuery := buildQuery (req )
3930 search := bleve .NewSearchRequest (reqQuery )
40- search .SortBy ([]string {"name" })
31+ search .SortBy ([]string {"name" , "_id" })
4132 search .From = (req .Page - 1 ) * req .PerPage
4233 search .Size = req .PerPage
4334 search .Fields = []string {"*" }
@@ -47,14 +38,74 @@ func (b *Bleve) Search(ctx context.Context, req model.SearchReq) ([]model.Search
4738 return nil , 0 , err
4839 }
4940 res , err := utils .SliceConvert (searchResults .Hits , func (src * search2.DocumentMatch ) (model.SearchNode , error ) {
50- return model.SearchNode {
51- Parent : src .Fields ["parent" ].(string ),
52- Name : src .Fields ["name" ].(string ),
53- IsDir : src .Fields ["is_dir" ].(bool ),
54- Size : int64 (src .Fields ["size" ].(float64 )),
55- }, nil
41+ return searchNodeFromHit (src ), nil
5642 })
57- return res , int64 (searchResults .Total ), nil
43+ return res , int64 (searchResults .Total ), err
44+ }
45+
46+ const searchBatchSize = 1000
47+
48+ func (b * Bleve ) SearchFiltered (ctx context.Context , req model.SearchReq , filter searcher.Filter ) ([]model.SearchNode , int64 , error ) {
49+ reqQuery := buildQuery (req )
50+ from := int64 (req .Page - 1 ) * int64 (req .PerPage )
51+ to := from + int64 (req .PerPage )
52+ var (
53+ result []model.SearchNode
54+ total int64
55+ searchAfter []string
56+ )
57+ for {
58+ search := bleve .NewSearchRequest (reqQuery )
59+ search .SortBy ([]string {"name" , "_id" })
60+ search .Size = searchBatchSize
61+ search .Fields = []string {"*" }
62+ if searchAfter != nil {
63+ search .SetSearchAfter (searchAfter )
64+ }
65+ searchResults , err := b .BIndex .Search (search )
66+ if err != nil {
67+ log .Errorf ("search error: %+v" , err )
68+ return nil , 0 , err
69+ }
70+ for _ , hit := range searchResults .Hits {
71+ node := searchNodeFromHit (hit )
72+ if ! utils .IsSubPath (req .Parent , node .Parent ) || filter != nil && ! filter (node ) {
73+ continue
74+ }
75+ if total >= from && total < to {
76+ result = append (result , node )
77+ }
78+ total ++
79+ }
80+ if len (searchResults .Hits ) < searchBatchSize {
81+ break
82+ }
83+ last := searchResults .Hits [len (searchResults .Hits )- 1 ]
84+ searchAfter = append (searchAfter [:0 ], last .Sort ... )
85+ }
86+ return result , total , nil
87+ }
88+
89+ func buildQuery (req model.SearchReq ) query2.Query {
90+ var queries []query2.Query
91+ query := bleve .NewMatchQuery (req .Keywords )
92+ query .SetField ("name" )
93+ queries = append (queries , query )
94+ if req .Scope != 0 {
95+ isDir := req .Scope == 1
96+ isDirQuery := bleve .NewBoolFieldQuery (isDir )
97+ queries = append (queries , isDirQuery )
98+ }
99+ return bleve .NewConjunctionQuery (queries ... )
100+ }
101+
102+ func searchNodeFromHit (src * search2.DocumentMatch ) model.SearchNode {
103+ return model.SearchNode {
104+ Parent : src .Fields ["parent" ].(string ),
105+ Name : src .Fields ["name" ].(string ),
106+ IsDir : src .Fields ["is_dir" ].(bool ),
107+ Size : int64 (src .Fields ["size" ].(float64 )),
108+ }
58109}
59110
60111func (b * Bleve ) Index (ctx context.Context , node model.SearchNode ) error {
@@ -103,3 +154,4 @@ func (b *Bleve) Clear(ctx context.Context) error {
103154}
104155
105156var _ searcher.Searcher = (* Bleve )(nil )
157+ var _ searcher.FilteredSearcher = (* Bleve )(nil )
0 commit comments