@@ -17,6 +17,7 @@ import (
1717 "code.gitea.io/gitea/modules/charset"
1818 "code.gitea.io/gitea/modules/git"
1919 "code.gitea.io/gitea/modules/gitrepo"
20+ path_filter "code.gitea.io/gitea/modules/indexer/code/bleve/token/path"
2021 "code.gitea.io/gitea/modules/indexer/code/internal"
2122 indexer_internal "code.gitea.io/gitea/modules/indexer/internal"
2223 inner_bleve "code.gitea.io/gitea/modules/indexer/internal/bleve"
@@ -53,6 +54,7 @@ type RepoIndexerData struct {
5354 RepoID int64
5455 CommitID string
5556 Content string
57+ Filename string
5658 Language string
5759 UpdatedAt time.Time
5860}
@@ -64,8 +66,10 @@ func (d *RepoIndexerData) Type() string {
6466
6567const (
6668 repoIndexerAnalyzer = "repoIndexerAnalyzer"
69+ filenameIndexerAnalyzer = "filenameIndexerAnalyzer"
70+ filenameIndexerTokenizer = "filenameIndexerTokenizer"
6771 repoIndexerDocType = "repoIndexerDocType"
68- repoIndexerLatestVersion = 6
72+ repoIndexerLatestVersion = 7
6973)
7074
7175// generateBleveIndexMapping generates a bleve index mapping for the repo indexer
@@ -79,6 +83,11 @@ func generateBleveIndexMapping() (mapping.IndexMapping, error) {
7983 textFieldMapping .IncludeInAll = false
8084 docMapping .AddFieldMappingsAt ("Content" , textFieldMapping )
8185
86+ fileNamedMapping := bleve .NewTextFieldMapping ()
87+ fileNamedMapping .IncludeInAll = false
88+ fileNamedMapping .Analyzer = filenameIndexerAnalyzer
89+ docMapping .AddFieldMappingsAt ("Filename" , fileNamedMapping )
90+
8291 termFieldMapping := bleve .NewTextFieldMapping ()
8392 termFieldMapping .IncludeInAll = false
8493 termFieldMapping .Analyzer = analyzer_keyword .Name
@@ -90,6 +99,7 @@ func generateBleveIndexMapping() (mapping.IndexMapping, error) {
9099 docMapping .AddFieldMappingsAt ("UpdatedAt" , timeFieldMapping )
91100
92101 mapping := bleve .NewIndexMapping ()
102+
93103 if err := addUnicodeNormalizeTokenFilter (mapping ); err != nil {
94104 return nil , err
95105 } else if err := mapping .AddCustomAnalyzer (repoIndexerAnalyzer , map [string ]any {
@@ -100,6 +110,16 @@ func generateBleveIndexMapping() (mapping.IndexMapping, error) {
100110 }); err != nil {
101111 return nil , err
102112 }
113+
114+ if err := mapping .AddCustomAnalyzer (filenameIndexerAnalyzer , map [string ]any {
115+ "type" : analyzer_custom .Name ,
116+ "char_filters" : []string {},
117+ "tokenizer" : unicode .Name ,
118+ "token_filters" : []string {unicodeNormalizeName , path_filter .Name , lowercase .Name },
119+ }); err != nil {
120+ return nil , err
121+ }
122+
103123 mapping .DefaultAnalyzer = repoIndexerAnalyzer
104124 mapping .AddDocumentMapping (repoIndexerDocType , docMapping )
105125 mapping .AddDocumentMapping ("_all" , bleve .NewDocumentDisabledMapping ())
@@ -174,6 +194,7 @@ func (b *Indexer) addUpdate(ctx context.Context, batchWriter git.WriteCloserErro
174194 return batch .Index (id , & RepoIndexerData {
175195 RepoID : repo .ID ,
176196 CommitID : commitSha ,
197+ Filename : update .Filename ,
177198 Content : string (charset .ToUTF8DropErrors (fileContents , charset.ConvertOpts {})),
178199 Language : analyze .GetCodeLanguage (update .Filename , fileContents ),
179200 UpdatedAt : time .Now ().UTC (),
@@ -240,14 +261,19 @@ func (b *Indexer) Search(ctx context.Context, opts *internal.SearchOptions) (int
240261 keywordQuery query.Query
241262 )
242263
243- phraseQuery := bleve .NewMatchPhraseQuery (opts .Keyword )
244- phraseQuery .FieldVal = "Content"
245- phraseQuery .Analyzer = repoIndexerAnalyzer
246- keywordQuery = phraseQuery
264+ pathQuery := bleve .NewPrefixQuery (strings .ToLower (opts .Keyword ))
265+ pathQuery .FieldVal = "Filename"
266+ pathQuery .SetBoost (10 )
267+
268+ contentQuery := bleve .NewMatchQuery (opts .Keyword )
269+ contentQuery .FieldVal = "Content"
270+
247271 if opts .IsKeywordFuzzy {
248- phraseQuery .Fuzziness = inner_bleve .GuessFuzzinessByKeyword (opts .Keyword )
272+ contentQuery .Fuzziness = inner_bleve .GuessFuzzinessByKeyword (opts .Keyword )
249273 }
250274
275+ keywordQuery = bleve .NewDisjunctionQuery (contentQuery , pathQuery )
276+
251277 if len (opts .RepoIDs ) > 0 {
252278 repoQueries := make ([]query.Query , 0 , len (opts .RepoIDs ))
253279 for _ , repoID := range opts .RepoIDs {
@@ -277,7 +303,7 @@ func (b *Indexer) Search(ctx context.Context, opts *internal.SearchOptions) (int
277303
278304 from , pageSize := opts .GetSkipTake ()
279305 searchRequest := bleve .NewSearchRequestOptions (indexerQuery , pageSize , from , false )
280- searchRequest .Fields = []string {"Content" , "RepoID" , "Language" , "CommitID" , "UpdatedAt" }
306+ searchRequest .Fields = []string {"Content" , "Filename" , " RepoID" , "Language" , "CommitID" , "UpdatedAt" }
281307 searchRequest .IncludeLocations = true
282308
283309 if len (opts .Language ) == 0 {
@@ -307,6 +333,10 @@ func (b *Indexer) Search(ctx context.Context, opts *internal.SearchOptions) (int
307333 endIndex = locationEnd
308334 }
309335 }
336+ if len (hit .Locations ["Filename" ]) > 0 {
337+ startIndex , endIndex = internal .FilenameMatchIndexPos (hit .Fields ["Content" ].(string ))
338+ }
339+
310340 language := hit .Fields ["Language" ].(string )
311341 var updatedUnix timeutil.TimeStamp
312342 if t , err := time .Parse (time .RFC3339 , hit .Fields ["UpdatedAt" ].(string )); err == nil {
0 commit comments