From 7bfe539991416c6f6b1cf96219d9cb6a281d5876 Mon Sep 17 00:00:00 2001 From: silkentrance Date: Mon, 24 Jun 2024 20:44:46 +0200 Subject: [PATCH] fix #4479: add issue/pull id to search --- modules/indexer/issues/bleve/bleve.go | 10 ++++++++-- modules/indexer/issues/db/db.go | 7 ++++++- modules/indexer/issues/elasticsearch/elasticsearch.go | 2 +- modules/indexer/issues/indexer.go | 7 +++++++ modules/indexer/issues/internal/model.go | 2 ++ modules/indexer/issues/meilisearch/meilisearch.go | 2 ++ 6 files changed, 26 insertions(+), 4 deletions(-) diff --git a/modules/indexer/issues/bleve/bleve.go b/modules/indexer/issues/bleve/bleve.go index 7ef370e89c5d2..d9b3f809a78fb 100644 --- a/modules/indexer/issues/bleve/bleve.go +++ b/modules/indexer/issues/bleve/bleve.go @@ -53,6 +53,7 @@ func generateIssueIndexMapping() (mapping.IndexMapping, error) { numericFieldMapping := bleve.NewNumericFieldMapping() numericFieldMapping.Store = false numericFieldMapping.IncludeInAll = false + docMapping.AddFieldMappingsAt("id", numericFieldMapping) docMapping.AddFieldMappingsAt("repo_id", numericFieldMapping) textFieldMapping := bleve.NewTextFieldMapping() @@ -161,11 +162,16 @@ func (b *Indexer) Search(ctx context.Context, options *internal.SearchOptions) ( fuzziness = inner_bleve.GuessFuzzinessByKeyword(options.Keyword) } - queries = append(queries, bleve.NewDisjunctionQuery([]query.Query{ + innerQueries := []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 options.IssueID.Has() { + innerQueries = append(innerQueries, inner_bleve.NumericEqualityQuery(options.IssueID.Value(), "id")) + } + + queries = append(queries, bleve.NewDisjunctionQuery(innerQueries...)) } if len(options.RepoIDs) > 0 || options.AllPublic { diff --git a/modules/indexer/issues/db/db.go b/modules/indexer/issues/db/db.go index 05ec548435f48..f0757ffcab0c4 100644 --- a/modules/indexer/issues/db/db.go +++ b/modules/indexer/issues/db/db.go @@ -51,7 +51,6 @@ func (i *Indexer) Search(ctx context.Context, options *internal.SearchOptions) ( // The notification is defined in modules, but it's using lots of things should be in services. cond := builder.NewCond() - if options.Keyword != "" { repoCond := builder.In("repo_id", options.RepoIDs) if len(options.RepoIDs) == 1 { @@ -59,6 +58,11 @@ func (i *Indexer) Search(ctx context.Context, options *internal.SearchOptions) ( } subQuery := builder.Select("id").From("issue").Where(repoCond) + var issueIDEq builder.Cond + issueIDEq = nil + if options.IssueID.Has() { + issueIDEq = builder.Eq{"issue.id": options.Keyword} + } cond = builder.Or( db.BuildCaseInsensitiveLike("issue.name", options.Keyword), db.BuildCaseInsensitiveLike("issue.content", options.Keyword), @@ -70,6 +74,7 @@ func (i *Indexer) Search(ctx context.Context, options *internal.SearchOptions) ( db.BuildCaseInsensitiveLike("content", options.Keyword), )), ), + issueIDEq, ) } diff --git a/modules/indexer/issues/elasticsearch/elasticsearch.go b/modules/indexer/issues/elasticsearch/elasticsearch.go index 6f705150097f6..b374cebb6de1f 100644 --- a/modules/indexer/issues/elasticsearch/elasticsearch.go +++ b/modules/indexer/issues/elasticsearch/elasticsearch.go @@ -150,7 +150,7 @@ func (b *Indexer) Search(ctx context.Context, options *internal.SearchOptions) ( searchType = esMultiMatchTypeBestFields } - query.Must(elastic.NewMultiMatchQuery(options.Keyword, "title", "content", "comments").Type(searchType)) + query.Must(elastic.NewMultiMatchQuery(options.Keyword, "id", "title", "content", "comments").Type(searchType)) } if len(options.RepoIDs) > 0 { diff --git a/modules/indexer/issues/indexer.go b/modules/indexer/issues/indexer.go index 1cb86feb82c28..8898967794de4 100644 --- a/modules/indexer/issues/indexer.go +++ b/modules/indexer/issues/indexer.go @@ -8,6 +8,7 @@ import ( "fmt" "os" "runtime/pprof" + "strconv" "sync/atomic" "time" @@ -283,6 +284,7 @@ const ( func SearchIssues(ctx context.Context, opts *SearchOptions) ([]int64, int64, error) { indexer := *globalIndexer.Load() + log.Info("Indexer Keyword: " + opts.Keyword) if opts.Keyword == "" { // This is a conservative shortcut. // If the keyword is empty, db has better (at least not worse) performance to filter issues. @@ -291,6 +293,11 @@ func SearchIssues(ctx context.Context, opts *SearchOptions) ([]int64, int64, err // Even worse, the external indexer like elastic search may not be available for a while, // and the user may not be able to list issues completely until it is available again. indexer = db.NewIndexer() + } else { + issueID, err := strconv.Atoi(opts.Keyword) + if err == nil { + opts.IssueID = optional.Option[int64]{int64(issueID)} + } } result, err := indexer.Search(ctx, opts) diff --git a/modules/indexer/issues/internal/model.go b/modules/indexer/issues/internal/model.go index 2dfee8b72e197..e6c79cfc4d669 100644 --- a/modules/indexer/issues/internal/model.go +++ b/modules/indexer/issues/internal/model.go @@ -89,6 +89,8 @@ type SearchOptions struct { MilestoneIDs []int64 // milestones the issues have + IssueID optional.Option[int64] // keyword as potential issue id + ProjectID optional.Option[int64] // project the issues belong to ProjectColumnID optional.Option[int64] // project column the issues belong to diff --git a/modules/indexer/issues/meilisearch/meilisearch.go b/modules/indexer/issues/meilisearch/meilisearch.go index 9332319339215..c09607aa4d81d 100644 --- a/modules/indexer/issues/meilisearch/meilisearch.go +++ b/modules/indexer/issues/meilisearch/meilisearch.go @@ -46,6 +46,7 @@ func NewIndexer(url, apiKey, indexerName string) *Indexer { "words", "typo", "proximity", "attribute", "exactness"}, SearchableAttributes: []string{ + "id", "title", "content", "comments", @@ -57,6 +58,7 @@ func NewIndexer(url, apiKey, indexerName string) *Indexer { "comments", }, FilterableAttributes: []string{ + "id", "repo_id", "is_public", "is_pull",