summaryrefslogtreecommitdiffstats
path: root/modules/indexer
diff options
context:
space:
mode:
authorJui-Nan Lin <jnlinn@gmail.com>2021-01-27 18:00:35 +0800
committerGitHub <noreply@github.com>2021-01-27 12:00:35 +0200
commitc10503afeccd5172ace7613094dd5fe1e0770c55 (patch)
tree5a39cbf125f38a3bc75eb77c689b03ed13efa44c /modules/indexer
parentb2c20b68a08e23bc952402a553d59a4613188bd0 (diff)
downloadgitea-c10503afeccd5172ace7613094dd5fe1e0770c55.tar.gz
gitea-c10503afeccd5172ace7613094dd5fe1e0770c55.zip
[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 <lauris@nix.lv> Co-authored-by: techknowlogick <techknowlogick@gitea.io>
Diffstat (limited to 'modules/indexer')
-rw-r--r--modules/indexer/code/bleve.go25
-rw-r--r--modules/indexer/code/elastic_search.go13
-rw-r--r--modules/indexer/code/indexer.go2
-rw-r--r--modules/indexer/code/indexer_test.go2
-rw-r--r--modules/indexer/code/search.go4
-rw-r--r--modules/indexer/code/wrapped.go4
6 files changed, 35 insertions, 15 deletions
diff --git a/modules/indexer/code/bleve.go b/modules/indexer/code/bleve.go
index b0822ad222..826efde4c1 100644
--- a/modules/indexer/code/bleve.go
+++ b/modules/indexer/code/bleve.go
@@ -280,12 +280,23 @@ func (b *BleveIndexer) Delete(repoID int64) error {
// Search searches for files in the specified repo.
// Returns the matching file-paths
-func (b *BleveIndexer) Search(repoIDs []int64, language, keyword string, page, pageSize int) (int64, []*SearchResult, []*SearchResultLanguages, error) {
- phraseQuery := bleve.NewMatchPhraseQuery(keyword)
- phraseQuery.FieldVal = "Content"
- phraseQuery.Analyzer = repoIndexerAnalyzer
+func (b *BleveIndexer) Search(repoIDs []int64, language, keyword string, page, pageSize int, isMatch bool) (int64, []*SearchResult, []*SearchResultLanguages, error) {
+ var (
+ indexerQuery query.Query
+ keywordQuery query.Query
+ )
+
+ if isMatch {
+ prefixQuery := bleve.NewPrefixQuery(keyword)
+ prefixQuery.FieldVal = "Content"
+ keywordQuery = prefixQuery
+ } else {
+ phraseQuery := bleve.NewMatchPhraseQuery(keyword)
+ phraseQuery.FieldVal = "Content"
+ phraseQuery.Analyzer = repoIndexerAnalyzer
+ keywordQuery = phraseQuery
+ }
- var indexerQuery query.Query
if len(repoIDs) > 0 {
var repoQueries = make([]query.Query, 0, len(repoIDs))
for _, repoID := range repoIDs {
@@ -294,10 +305,10 @@ func (b *BleveIndexer) Search(repoIDs []int64, language, keyword string, page, p
indexerQuery = bleve.NewConjunctionQuery(
bleve.NewDisjunctionQuery(repoQueries...),
- phraseQuery,
+ keywordQuery,
)
} else {
- indexerQuery = phraseQuery
+ indexerQuery = keywordQuery
}
// Save for reuse without language filter
diff --git a/modules/indexer/code/elastic_search.go b/modules/indexer/code/elastic_search.go
index 0f61c4e592..f81dbb34d4 100644
--- a/modules/indexer/code/elastic_search.go
+++ b/modules/indexer/code/elastic_search.go
@@ -27,6 +27,10 @@ import (
const (
esRepoIndexerLatestVersion = 1
+ // multi-match-types, currently only 2 types are used
+ // Reference: https://www.elastic.co/guide/en/elasticsearch/reference/7.0/query-dsl-multi-match-query.html#multi-match-types
+ esMultiMatchTypeBestFields = "best_fields"
+ esMultiMatchTypePhrasePrefix = "phrase_prefix"
)
var (
@@ -330,8 +334,13 @@ func extractAggs(searchResult *elastic.SearchResult) []*SearchResultLanguages {
}
// Search searches for codes and language stats by given conditions.
-func (b *ElasticSearchIndexer) Search(repoIDs []int64, language, keyword string, page, pageSize int) (int64, []*SearchResult, []*SearchResultLanguages, error) {
- kwQuery := elastic.NewMultiMatchQuery(keyword, "content")
+func (b *ElasticSearchIndexer) Search(repoIDs []int64, language, keyword string, page, pageSize int, isMatch bool) (int64, []*SearchResult, []*SearchResultLanguages, error) {
+ searchType := esMultiMatchTypeBestFields
+ if isMatch {
+ searchType = esMultiMatchTypePhrasePrefix
+ }
+
+ kwQuery := elastic.NewMultiMatchQuery(keyword, "content").Type(searchType)
query := elastic.NewBoolQuery()
query = query.Must(kwQuery)
if len(repoIDs) > 0 {
diff --git a/modules/indexer/code/indexer.go b/modules/indexer/code/indexer.go
index 35c298a548..a7d78e9fdc 100644
--- a/modules/indexer/code/indexer.go
+++ b/modules/indexer/code/indexer.go
@@ -43,7 +43,7 @@ type SearchResultLanguages struct {
type Indexer interface {
Index(repo *models.Repository, sha string, changes *repoChanges) error
Delete(repoID int64) error
- Search(repoIDs []int64, language, keyword string, page, pageSize int) (int64, []*SearchResult, []*SearchResultLanguages, error)
+ Search(repoIDs []int64, language, keyword string, page, pageSize int, isMatch bool) (int64, []*SearchResult, []*SearchResultLanguages, error)
Close()
}
diff --git a/modules/indexer/code/indexer_test.go b/modules/indexer/code/indexer_test.go
index 0b4851a48a..8fcb7a0e8a 100644
--- a/modules/indexer/code/indexer_test.go
+++ b/modules/indexer/code/indexer_test.go
@@ -64,7 +64,7 @@ func testIndexer(name string, t *testing.T, indexer Indexer) {
for _, kw := range keywords {
t.Run(kw.Keyword, func(t *testing.T) {
- total, res, langs, err := indexer.Search(kw.RepoIDs, "", kw.Keyword, 1, 10)
+ total, res, langs, err := indexer.Search(kw.RepoIDs, "", kw.Keyword, 1, 10, false)
assert.NoError(t, err)
assert.EqualValues(t, len(kw.IDs), total)
assert.EqualValues(t, kw.Langs, len(langs))
diff --git a/modules/indexer/code/search.go b/modules/indexer/code/search.go
index 29ed416541..51b7c9427d 100644
--- a/modules/indexer/code/search.go
+++ b/modules/indexer/code/search.go
@@ -106,12 +106,12 @@ func searchResult(result *SearchResult, startIndex, endIndex int) (*Result, erro
}
// PerformSearch perform a search on a repository
-func PerformSearch(repoIDs []int64, language, keyword string, page, pageSize int) (int, []*Result, []*SearchResultLanguages, error) {
+func PerformSearch(repoIDs []int64, language, keyword string, page, pageSize int, isMatch bool) (int, []*Result, []*SearchResultLanguages, error) {
if len(keyword) == 0 {
return 0, nil, nil, nil
}
- total, results, resultLanguages, err := indexer.Search(repoIDs, language, keyword, page, pageSize)
+ total, results, resultLanguages, err := indexer.Search(repoIDs, language, keyword, page, pageSize, isMatch)
if err != nil {
return 0, nil, nil, err
}
diff --git a/modules/indexer/code/wrapped.go b/modules/indexer/code/wrapped.go
index d839544874..5b19f9c625 100644
--- a/modules/indexer/code/wrapped.go
+++ b/modules/indexer/code/wrapped.go
@@ -73,12 +73,12 @@ func (w *wrappedIndexer) Delete(repoID int64) error {
return indexer.Delete(repoID)
}
-func (w *wrappedIndexer) Search(repoIDs []int64, language, keyword string, page, pageSize int) (int64, []*SearchResult, []*SearchResultLanguages, error) {
+func (w *wrappedIndexer) Search(repoIDs []int64, language, keyword string, page, pageSize int, isMatch bool) (int64, []*SearchResult, []*SearchResultLanguages, error) {
indexer, err := w.get()
if err != nil {
return 0, nil, nil, err
}
- return indexer.Search(repoIDs, language, keyword, page, pageSize)
+ return indexer.Search(repoIDs, language, keyword, page, pageSize, isMatch)
}