Skip to content

Commit c10503a

Browse files
jnlinlafrikstechknowlogick
authored
[Feature] add precise search type for Elastic Search (#12869)
* feat: add type query parameters for specifying precise search * feat: add select dropdown in search box Co-authored-by: Lauris BH <[email protected]> Co-authored-by: techknowlogick <[email protected]>
1 parent b2c20b6 commit c10503a

File tree

12 files changed

+77
-25
lines changed

12 files changed

+77
-25
lines changed

modules/context/pagination.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,4 +53,5 @@ func (p *Pagination) SetDefaultParams(ctx *Context) {
5353
p.AddParam(ctx, "sort", "SortType")
5454
p.AddParam(ctx, "q", "Keyword")
5555
p.AddParam(ctx, "tab", "TabName")
56+
p.AddParam(ctx, "t", "queryType")
5657
}

modules/indexer/code/bleve.go

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -280,12 +280,23 @@ func (b *BleveIndexer) Delete(repoID int64) error {
280280

281281
// Search searches for files in the specified repo.
282282
// Returns the matching file-paths
283-
func (b *BleveIndexer) Search(repoIDs []int64, language, keyword string, page, pageSize int) (int64, []*SearchResult, []*SearchResultLanguages, error) {
284-
phraseQuery := bleve.NewMatchPhraseQuery(keyword)
285-
phraseQuery.FieldVal = "Content"
286-
phraseQuery.Analyzer = repoIndexerAnalyzer
283+
func (b *BleveIndexer) Search(repoIDs []int64, language, keyword string, page, pageSize int, isMatch bool) (int64, []*SearchResult, []*SearchResultLanguages, error) {
284+
var (
285+
indexerQuery query.Query
286+
keywordQuery query.Query
287+
)
288+
289+
if isMatch {
290+
prefixQuery := bleve.NewPrefixQuery(keyword)
291+
prefixQuery.FieldVal = "Content"
292+
keywordQuery = prefixQuery
293+
} else {
294+
phraseQuery := bleve.NewMatchPhraseQuery(keyword)
295+
phraseQuery.FieldVal = "Content"
296+
phraseQuery.Analyzer = repoIndexerAnalyzer
297+
keywordQuery = phraseQuery
298+
}
287299

288-
var indexerQuery query.Query
289300
if len(repoIDs) > 0 {
290301
var repoQueries = make([]query.Query, 0, len(repoIDs))
291302
for _, repoID := range repoIDs {
@@ -294,10 +305,10 @@ func (b *BleveIndexer) Search(repoIDs []int64, language, keyword string, page, p
294305

295306
indexerQuery = bleve.NewConjunctionQuery(
296307
bleve.NewDisjunctionQuery(repoQueries...),
297-
phraseQuery,
308+
keywordQuery,
298309
)
299310
} else {
300-
indexerQuery = phraseQuery
311+
indexerQuery = keywordQuery
301312
}
302313

303314
// Save for reuse without language filter

modules/indexer/code/elastic_search.go

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ import (
2727

2828
const (
2929
esRepoIndexerLatestVersion = 1
30+
// multi-match-types, currently only 2 types are used
31+
// Reference: https://www.elastic.co/guide/en/elasticsearch/reference/7.0/query-dsl-multi-match-query.html#multi-match-types
32+
esMultiMatchTypeBestFields = "best_fields"
33+
esMultiMatchTypePhrasePrefix = "phrase_prefix"
3034
)
3135

3236
var (
@@ -330,8 +334,13 @@ func extractAggs(searchResult *elastic.SearchResult) []*SearchResultLanguages {
330334
}
331335

332336
// Search searches for codes and language stats by given conditions.
333-
func (b *ElasticSearchIndexer) Search(repoIDs []int64, language, keyword string, page, pageSize int) (int64, []*SearchResult, []*SearchResultLanguages, error) {
334-
kwQuery := elastic.NewMultiMatchQuery(keyword, "content")
337+
func (b *ElasticSearchIndexer) Search(repoIDs []int64, language, keyword string, page, pageSize int, isMatch bool) (int64, []*SearchResult, []*SearchResultLanguages, error) {
338+
searchType := esMultiMatchTypeBestFields
339+
if isMatch {
340+
searchType = esMultiMatchTypePhrasePrefix
341+
}
342+
343+
kwQuery := elastic.NewMultiMatchQuery(keyword, "content").Type(searchType)
335344
query := elastic.NewBoolQuery()
336345
query = query.Must(kwQuery)
337346
if len(repoIDs) > 0 {

modules/indexer/code/indexer.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ type SearchResultLanguages struct {
4343
type Indexer interface {
4444
Index(repo *models.Repository, sha string, changes *repoChanges) error
4545
Delete(repoID int64) error
46-
Search(repoIDs []int64, language, keyword string, page, pageSize int) (int64, []*SearchResult, []*SearchResultLanguages, error)
46+
Search(repoIDs []int64, language, keyword string, page, pageSize int, isMatch bool) (int64, []*SearchResult, []*SearchResultLanguages, error)
4747
Close()
4848
}
4949

modules/indexer/code/indexer_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ func testIndexer(name string, t *testing.T, indexer Indexer) {
6464

6565
for _, kw := range keywords {
6666
t.Run(kw.Keyword, func(t *testing.T) {
67-
total, res, langs, err := indexer.Search(kw.RepoIDs, "", kw.Keyword, 1, 10)
67+
total, res, langs, err := indexer.Search(kw.RepoIDs, "", kw.Keyword, 1, 10, false)
6868
assert.NoError(t, err)
6969
assert.EqualValues(t, len(kw.IDs), total)
7070
assert.EqualValues(t, kw.Langs, len(langs))

modules/indexer/code/search.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,12 +106,12 @@ func searchResult(result *SearchResult, startIndex, endIndex int) (*Result, erro
106106
}
107107

108108
// PerformSearch perform a search on a repository
109-
func PerformSearch(repoIDs []int64, language, keyword string, page, pageSize int) (int, []*Result, []*SearchResultLanguages, error) {
109+
func PerformSearch(repoIDs []int64, language, keyword string, page, pageSize int, isMatch bool) (int, []*Result, []*SearchResultLanguages, error) {
110110
if len(keyword) == 0 {
111111
return 0, nil, nil, nil
112112
}
113113

114-
total, results, resultLanguages, err := indexer.Search(repoIDs, language, keyword, page, pageSize)
114+
total, results, resultLanguages, err := indexer.Search(repoIDs, language, keyword, page, pageSize, isMatch)
115115
if err != nil {
116116
return 0, nil, nil, err
117117
}

modules/indexer/code/wrapped.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,12 +73,12 @@ func (w *wrappedIndexer) Delete(repoID int64) error {
7373
return indexer.Delete(repoID)
7474
}
7575

76-
func (w *wrappedIndexer) Search(repoIDs []int64, language, keyword string, page, pageSize int) (int64, []*SearchResult, []*SearchResultLanguages, error) {
76+
func (w *wrappedIndexer) Search(repoIDs []int64, language, keyword string, page, pageSize int, isMatch bool) (int64, []*SearchResult, []*SearchResultLanguages, error) {
7777
indexer, err := w.get()
7878
if err != nil {
7979
return 0, nil, nil, err
8080
}
81-
return indexer.Search(repoIDs, language, keyword, page, pageSize)
81+
return indexer.Search(repoIDs, language, keyword, page, pageSize, isMatch)
8282

8383
}
8484

options/locale/locale_en-US.ini

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,8 @@ users = Users
237237
organizations = Organizations
238238
search = Search
239239
code = Code
240+
search.fuzzy = Fuzzy
241+
search.match = Match
240242
repo_no_results = No matching repositories found.
241243
user_no_results = No matching users found.
242244
org_no_results = No matching organizations found.
@@ -1462,6 +1464,8 @@ activity.git_stats_deletion_n = %d deletions
14621464
14631465
search = Search
14641466
search.search_repo = Search repository
1467+
search.fuzzy = Fuzzy
1468+
search.match = Match
14651469
search.results = Search results for "%s" in <a href="%s">%s</a>
14661470
14671471
settings = Settings

routers/home.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,9 @@ func ExploreCode(ctx *context.Context) {
299299
page = 1
300300
}
301301

302+
queryType := strings.TrimSpace(ctx.Query("t"))
303+
isMatch := queryType == "match"
304+
302305
var (
303306
repoIDs []int64
304307
err error
@@ -342,14 +345,14 @@ func ExploreCode(ctx *context.Context) {
342345

343346
ctx.Data["RepoMaps"] = rightRepoMap
344347

345-
total, searchResults, searchResultLanguages, err = code_indexer.PerformSearch(repoIDs, language, keyword, page, setting.UI.RepoSearchPagingNum)
348+
total, searchResults, searchResultLanguages, err = code_indexer.PerformSearch(repoIDs, language, keyword, page, setting.UI.RepoSearchPagingNum, isMatch)
346349
if err != nil {
347350
ctx.ServerError("SearchResults", err)
348351
return
349352
}
350353
// if non-login user or isAdmin, no need to check UnitTypeCode
351354
} else if (ctx.User == nil && len(repoIDs) > 0) || isAdmin {
352-
total, searchResults, searchResultLanguages, err = code_indexer.PerformSearch(repoIDs, language, keyword, page, setting.UI.RepoSearchPagingNum)
355+
total, searchResults, searchResultLanguages, err = code_indexer.PerformSearch(repoIDs, language, keyword, page, setting.UI.RepoSearchPagingNum, isMatch)
353356
if err != nil {
354357
ctx.ServerError("SearchResults", err)
355358
return
@@ -380,6 +383,7 @@ func ExploreCode(ctx *context.Context) {
380383

381384
ctx.Data["Keyword"] = keyword
382385
ctx.Data["Language"] = language
386+
ctx.Data["queryType"] = queryType
383387
ctx.Data["SearchResults"] = searchResults
384388
ctx.Data["SearchResultLanguages"] = searchResultLanguages
385389
ctx.Data["RequireHighlightJS"] = true

routers/repo/search.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,18 @@ func Search(ctx *context.Context) {
2828
if page <= 0 {
2929
page = 1
3030
}
31+
queryType := strings.TrimSpace(ctx.Query("t"))
32+
isMatch := queryType == "match"
33+
3134
total, searchResults, searchResultLanguages, err := code_indexer.PerformSearch([]int64{ctx.Repo.Repository.ID},
32-
language, keyword, page, setting.UI.RepoSearchPagingNum)
35+
language, keyword, page, setting.UI.RepoSearchPagingNum, isMatch)
3336
if err != nil {
3437
ctx.ServerError("SearchResults", err)
3538
return
3639
}
3740
ctx.Data["Keyword"] = keyword
3841
ctx.Data["Language"] = language
42+
ctx.Data["queryType"] = queryType
3943
ctx.Data["SourcePath"] = setting.AppSubURL + "/" +
4044
path.Join(ctx.Repo.Repository.Owner.Name, ctx.Repo.Repository.Name)
4145
ctx.Data["SearchResults"] = searchResults

templates/explore/code.tmpl

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,19 @@
55
<form class="ui form ignore-dirty" style="max-width: 100%">
66
<input type="hidden" name="tab" value="{{$.TabName}}">
77
<div class="ui fluid action input">
8+
<div class="twelve wide field">
89
<input name="q" value="{{.Keyword}}" placeholder="{{.i18n.Tr "explore.search"}}..." autofocus>
10+
</div>
11+
<div class="two wide field">
12+
<select name="t">
13+
<option value="">{{.i18n.Tr "explore.search.fuzzy"}}</option>
14+
<option value="match" {{if eq .queryType "match"}}selected{{end}}>{{.i18n.Tr "explore.search.match"}}</option>
15+
</select>
16+
</div>
17+
<div class="three field">
918
<button class="ui blue button">{{.i18n.Tr "explore.search"}}</button>
1019
</div>
20+
</div>
1121
</form>
1222
<div class="ui divider"></div>
1323

@@ -18,7 +28,7 @@
1828
</h3>
1929
<div class="df ac fw">
2030
{{range $term := .SearchResultLanguages}}
21-
<a class="ui text-label df ac mr-1 my-1 {{if eq $.Language $term.Language}}primary {{end}}basic label" href="{{AppSubUrl}}/explore/code?q={{$.Keyword}}{{if ne $.Language $term.Language}}&l={{$term.Language}}{{end}}">
31+
<a class="ui text-label df ac mr-1 my-1 {{if eq $.Language $term.Language}}primary {{end}}basic label" href="{{AppSubUrl}}/explore/code?q={{$.Keyword}}{{if ne $.Language $term.Language}}&l={{$term.Language}}{{end}}{{if ne $.queryType ""}}&t={{$.queryType}}{{end}}">
2232
<i class="color-icon mr-3" style="background-color: {{$term.Color}}"></i>
2333
{{$term.Language}}
2434
<div class="detail">{{$term.Count}}</div>
@@ -62,4 +72,3 @@
6272
</div>
6373
</div>
6474
{{template "base/footer" .}}
65-

templates/repo/search.tmpl

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,20 @@
55
<div class="ui repo-search">
66
<form class="ui form ignore-dirty" method="get">
77
<div class="ui fluid action input">
8-
<input name="q" value="{{.Keyword}}" placeholder="{{.i18n.Tr "repo.search.search_repo"}}">
9-
<button class="ui button" type="submit">
10-
<i class="icon df ac jc">{{svg "octicon-search" 16}}</i>
11-
</button>
8+
<div class="twelve wide field">
9+
<input name="q" value="{{.Keyword}}" placeholder="{{.i18n.Tr "repo.search.search_repo"}}">
10+
</div>
11+
<div class="two wide field">
12+
<select name="t">
13+
<option value="">{{.i18n.Tr "repo.search.fuzzy"}}</option>
14+
<option value="match" {{if eq .queryType "match"}}selected{{end}}>{{.i18n.Tr "repo.search.match"}}</option>
15+
</select>
16+
</div>
17+
<div class="three field">
18+
<button class="ui button" type="submit">
19+
<i class="icon df ac jc">{{svg "octicon-search" 16}}</i>
20+
</button>
21+
</div>
1222
</div>
1323
</form>
1424
</div>
@@ -18,7 +28,7 @@
1828
</h3>
1929
<div class="df ac fw">
2030
{{range $term := .SearchResultLanguages}}
21-
<a class="ui text-label df ac mr-1 my-1 {{if eq $.Language $term.Language}}primary {{end}}basic label" href="{{EscapePound $.SourcePath}}/search?q={{$.Keyword}}{{if ne $.Language $term.Language}}&l={{$term.Language}}{{end}}">
31+
<a class="ui text-label df ac mr-1 my-1 {{if eq $.Language $term.Language}}primary {{end}}basic label" href="{{EscapePound $.SourcePath}}/search?q={{$.Keyword}}{{if ne $.Language $term.Language}}&l={{$term.Language}}{{end}}{{if ne $.queryType ""}}&t={{$.queryType}}{{end}}">
2232
<i class="color-icon mr-3" style="background-color: {{$term.Color}}"></i>
2333
{{$term.Language}}
2434
<div class="detail">{{$term.Count}}</div>

0 commit comments

Comments
 (0)