mirror of
https://codeberg.org/davrot/forgejo.git
synced 2025-05-18 08:00:01 +02:00
feat(issue search): query string for boolean operators and phrase search (#6952)
closes #6909 related to forgejo/design#14 # Description Adds the following boolean operators for issues when using an indexer (with minor caveats) - `+term`: `term` MUST be present for any result - `-term`: negation; exclude results that contain `term` - `"this is a term"`: matches the exact phrase `this is a term` In all cases the special characters may be escaped by the prefix `\` Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6952 Reviewed-by: 0ko <0ko@noreply.codeberg.org> Reviewed-by: Otto <otto@codeberg.org> Co-authored-by: Shiny Nematoda <snematoda.751k2@aleeas.com> Co-committed-by: Shiny Nematoda <snematoda.751k2@aleeas.com>
This commit is contained in:
parent
eaa641c21e
commit
cddf608cb9
19 changed files with 451 additions and 192 deletions
|
@ -23,6 +23,10 @@ const (
|
|||
// 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"
|
||||
|
||||
// fuzziness options
|
||||
// Reference: https://www.elastic.co/guide/en/elasticsearch/reference/7.0/common-options.html#fuzziness
|
||||
esFuzzyAuto = "AUTO"
|
||||
)
|
||||
|
||||
var _ internal.Indexer = &Indexer{}
|
||||
|
@ -145,12 +149,30 @@ func (b *Indexer) Search(ctx context.Context, options *internal.SearchOptions) (
|
|||
query := elastic.NewBoolQuery()
|
||||
|
||||
if options.Keyword != "" {
|
||||
searchType := esMultiMatchTypePhrasePrefix
|
||||
if options.IsFuzzyKeyword {
|
||||
searchType = esMultiMatchTypeBestFields
|
||||
q := elastic.NewBoolQuery()
|
||||
tokens, err := options.Tokens()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, token := range tokens {
|
||||
innerQ := elastic.NewMultiMatchQuery(token.Term, "title", "content", "comments")
|
||||
if token.Fuzzy {
|
||||
// If the term is not a phrase use fuzziness set to AUTO
|
||||
innerQ = innerQ.Type(esMultiMatchTypeBestFields).Fuzziness(esFuzzyAuto)
|
||||
} else {
|
||||
innerQ = innerQ.Type(esMultiMatchTypePhrasePrefix)
|
||||
}
|
||||
|
||||
query.Must(elastic.NewMultiMatchQuery(options.Keyword, "title", "content", "comments").Type(searchType))
|
||||
switch token.Kind {
|
||||
case internal.BoolOptMust:
|
||||
q.Must(innerQ)
|
||||
case internal.BoolOptShould:
|
||||
q.Should(innerQ)
|
||||
case internal.BoolOptNot:
|
||||
q.MustNot(innerQ)
|
||||
}
|
||||
}
|
||||
query.Must(q)
|
||||
}
|
||||
|
||||
if len(options.RepoIDs) > 0 {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue