Skip to content

Commit

Permalink
Determine fuzziness of bleve indexer by keyword length (go-gitea#29706)
Browse files Browse the repository at this point in the history
also bleve did match on fuzzy search and the other way around. this also fix that bug.

(cherry picked from commit b9c57fb)

Conflicts:
	tests/integration/repo_search_test.go
	simple conflict resolution in the tests
  • Loading branch information
6543 authored and earl-warren committed Mar 26, 2024
1 parent b731171 commit ab5f0b7
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 37 deletions.
15 changes: 7 additions & 8 deletions modules/indexer/code/bleve/bleve.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ import (
const (
unicodeNormalizeName = "unicodeNormalize"
maxBatchSize = 16
// fuzzyDenominator determines the levenshtein distance per each character of a keyword
fuzzyDenominator = 4
)

func addUnicodeNormalizeTokenFilter(m *mapping.IndexMappingImpl) error {
Expand Down Expand Up @@ -239,15 +241,12 @@ func (b *Indexer) Search(ctx context.Context, opts *internal.SearchOptions) (int
keywordQuery query.Query
)

phraseQuery := bleve.NewMatchPhraseQuery(opts.Keyword)
phraseQuery.FieldVal = "Content"
phraseQuery.Analyzer = repoIndexerAnalyzer
keywordQuery = phraseQuery
if opts.IsKeywordFuzzy {
phraseQuery := bleve.NewMatchPhraseQuery(opts.Keyword)
phraseQuery.FieldVal = "Content"
phraseQuery.Analyzer = repoIndexerAnalyzer
keywordQuery = phraseQuery
} else {
prefixQuery := bleve.NewPrefixQuery(opts.Keyword)
prefixQuery.FieldVal = "Content"
keywordQuery = prefixQuery
phraseQuery.Fuzziness = len(opts.Keyword) / fuzzyDenominator
}

if len(opts.RepoIDs) > 0 {
Expand Down
10 changes: 2 additions & 8 deletions modules/indexer/internal/bleve/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,11 @@ func NumericEqualityQuery(value int64, field string) *query.NumericRangeQuery {
}

// MatchPhraseQuery generates a match phrase query for the given phrase, field and analyzer
func MatchPhraseQuery(matchPhrase, field, analyzer string) *query.MatchPhraseQuery {
func MatchPhraseQuery(matchPhrase, field, analyzer string, fuzziness int) *query.MatchPhraseQuery {
q := bleve.NewMatchPhraseQuery(matchPhrase)
q.FieldVal = field
q.Analyzer = analyzer
return q
}

// PrefixQuery generates a match prefix query for the given prefix and field
func PrefixQuery(matchPrefix, field string) *query.PrefixQuery {
q := bleve.NewPrefixQuery(matchPrefix)
q.FieldVal = field
q.Fuzziness = fuzziness
return q
}

Expand Down
25 changes: 13 additions & 12 deletions modules/indexer/issues/bleve/bleve.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,11 @@ func addUnicodeNormalizeTokenFilter(m *mapping.IndexMappingImpl) error {
})
}

const maxBatchSize = 16
const (
maxBatchSize = 16
// fuzzyDenominator determines the levenshtein distance per each character of a keyword
fuzzyDenominator = 4
)

// IndexerData an update to the issue indexer
type IndexerData internal.IndexerData
Expand Down Expand Up @@ -156,19 +160,16 @@ func (b *Indexer) Search(ctx context.Context, options *internal.SearchOptions) (
var queries []query.Query

if options.Keyword != "" {
fuzziness := 0
if options.IsFuzzyKeyword {
queries = append(queries, bleve.NewDisjunctionQuery([]query.Query{
inner_bleve.MatchPhraseQuery(options.Keyword, "title", issueIndexerAnalyzer),
inner_bleve.MatchPhraseQuery(options.Keyword, "content", issueIndexerAnalyzer),
inner_bleve.MatchPhraseQuery(options.Keyword, "comments", issueIndexerAnalyzer),
}...))
} else {
queries = append(queries, bleve.NewDisjunctionQuery([]query.Query{
inner_bleve.PrefixQuery(options.Keyword, "title"),
inner_bleve.PrefixQuery(options.Keyword, "content"),
inner_bleve.PrefixQuery(options.Keyword, "comments"),
}...))
fuzziness = len(options.Keyword) / fuzzyDenominator
}

queries = append(queries, bleve.NewDisjunctionQuery([]query.Query{
inner_bleve.MatchPhraseQuery(options.Keyword, "title", issueIndexerAnalyzer, fuzziness),
inner_bleve.MatchPhraseQuery(options.Keyword, "content", issueIndexerAnalyzer, fuzziness),
inner_bleve.MatchPhraseQuery(options.Keyword, "comments", issueIndexerAnalyzer, fuzziness),
}...))
}

if len(options.RepoIDs) > 0 || options.AllPublic {
Expand Down
16 changes: 7 additions & 9 deletions tests/integration/repo_search_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ func testSearchRepo(t *testing.T, useExternalIndexer bool) {

if useExternalIndexer {
gitReference = "/commit/"
executeIndexer(t, repo, code_indexer.UpdateRepoIndexer)
code_indexer.UpdateRepoIndexer(repo)
}

testSearch(t, "/user2/repo1/search?q=Description&page=1", gitReference, []string{"README.md"})
Expand All @@ -58,12 +58,14 @@ func testSearchRepo(t *testing.T, useExternalIndexer bool) {
repo, err = repo_model.GetRepositoryByOwnerAndName(db.DefaultContext, "user2", "glob")
assert.NoError(t, err)

executeIndexer(t, repo, code_indexer.UpdateRepoIndexer)
code_indexer.UpdateRepoIndexer(repo)

testSearch(t, "/user2/glob/search?q=loren&page=1", gitReference, []string{"a.txt"})
testSearch(t, "/user2/glob/search?q=file3&page=1", gitReference, []string{"x/b.txt"})
testSearch(t, "/user2/glob/search?q=file4&page=1", gitReference, []string{})
testSearch(t, "/user2/glob/search?q=file5&page=1", gitReference, []string{})
testSearch(t, "/user2/glob/search?q=loren&page=1&t=match", gitReference, []string{"a.txt"})
testSearch(t, "/user2/glob/search?q=file3&page=1", gitReference, []string{"x/b.txt", "a.txt"})
testSearch(t, "/user2/glob/search?q=file3&page=1&t=match", gitReference, []string{"x/b.txt", "a.txt"})
testSearch(t, "/user2/glob/search?q=file4&page=1&t=match", gitReference, []string{"x/b.txt", "a.txt"})
testSearch(t, "/user2/glob/search?q=file5&page=1&t=match", gitReference, []string{"x/b.txt", "a.txt"})
}
}

Expand All @@ -88,7 +90,3 @@ func testSearch(t *testing.T, url, gitRef string, expected []string) {

checkResultLinks(t, gitRef, doc)
}

func executeIndexer(t *testing.T, repo *repo_model.Repository, op func(*repo_model.Repository)) {
op(repo)
}

0 comments on commit ab5f0b7

Please sign in to comment.