mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-29 10:57:44 +09:00 
			
		
		
		
	* Issue search support elasticsearch * Fix lint * Add indexer name on app.ini * add a warnning on SearchIssuesByKeyword * improve code
		
			
				
	
	
		
			470 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Go
		
	
	
	
		
			Vendored
		
	
	
	
			
		
		
	
	
			470 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Go
		
	
	
	
		
			Vendored
		
	
	
	
| // Copyright 2012-present Oliver Eilhard. All rights reserved.
 | |
| // Use of this source code is governed by a MIT-license.
 | |
| // See http://olivere.mit-license.org/license.txt for details.
 | |
| 
 | |
| package elastic
 | |
| 
 | |
| // Highlight allows highlighting search results on one or more fields.
 | |
| // For details, see:
 | |
| // https://www.elastic.co/guide/en/elasticsearch/reference/7.0/search-request-highlighting.html
 | |
| type Highlight struct {
 | |
| 	fields                []*HighlighterField
 | |
| 	tagsSchema            *string
 | |
| 	highlightFilter       *bool
 | |
| 	fragmentSize          *int
 | |
| 	numOfFragments        *int
 | |
| 	preTags               []string
 | |
| 	postTags              []string
 | |
| 	order                 *string
 | |
| 	encoder               *string
 | |
| 	requireFieldMatch     *bool
 | |
| 	boundaryMaxScan       *int
 | |
| 	boundaryChars         *string
 | |
| 	boundaryScannerType   *string
 | |
| 	boundaryScannerLocale *string
 | |
| 	highlighterType       *string
 | |
| 	fragmenter            *string
 | |
| 	highlightQuery        Query
 | |
| 	noMatchSize           *int
 | |
| 	phraseLimit           *int
 | |
| 	options               map[string]interface{}
 | |
| 	forceSource           *bool
 | |
| 	useExplicitFieldOrder bool
 | |
| }
 | |
| 
 | |
| func NewHighlight() *Highlight {
 | |
| 	hl := &Highlight{
 | |
| 		options: make(map[string]interface{}),
 | |
| 	}
 | |
| 	return hl
 | |
| }
 | |
| 
 | |
| func (hl *Highlight) Fields(fields ...*HighlighterField) *Highlight {
 | |
| 	hl.fields = append(hl.fields, fields...)
 | |
| 	return hl
 | |
| }
 | |
| 
 | |
| func (hl *Highlight) Field(name string) *Highlight {
 | |
| 	field := NewHighlighterField(name)
 | |
| 	hl.fields = append(hl.fields, field)
 | |
| 	return hl
 | |
| }
 | |
| 
 | |
| func (hl *Highlight) TagsSchema(schemaName string) *Highlight {
 | |
| 	hl.tagsSchema = &schemaName
 | |
| 	return hl
 | |
| }
 | |
| 
 | |
| func (hl *Highlight) HighlightFilter(highlightFilter bool) *Highlight {
 | |
| 	hl.highlightFilter = &highlightFilter
 | |
| 	return hl
 | |
| }
 | |
| 
 | |
| func (hl *Highlight) FragmentSize(fragmentSize int) *Highlight {
 | |
| 	hl.fragmentSize = &fragmentSize
 | |
| 	return hl
 | |
| }
 | |
| 
 | |
| func (hl *Highlight) NumOfFragments(numOfFragments int) *Highlight {
 | |
| 	hl.numOfFragments = &numOfFragments
 | |
| 	return hl
 | |
| }
 | |
| 
 | |
| func (hl *Highlight) Encoder(encoder string) *Highlight {
 | |
| 	hl.encoder = &encoder
 | |
| 	return hl
 | |
| }
 | |
| 
 | |
| func (hl *Highlight) PreTags(preTags ...string) *Highlight {
 | |
| 	hl.preTags = append(hl.preTags, preTags...)
 | |
| 	return hl
 | |
| }
 | |
| 
 | |
| func (hl *Highlight) PostTags(postTags ...string) *Highlight {
 | |
| 	hl.postTags = append(hl.postTags, postTags...)
 | |
| 	return hl
 | |
| }
 | |
| 
 | |
| func (hl *Highlight) Order(order string) *Highlight {
 | |
| 	hl.order = &order
 | |
| 	return hl
 | |
| }
 | |
| 
 | |
| func (hl *Highlight) RequireFieldMatch(requireFieldMatch bool) *Highlight {
 | |
| 	hl.requireFieldMatch = &requireFieldMatch
 | |
| 	return hl
 | |
| }
 | |
| 
 | |
| func (hl *Highlight) BoundaryMaxScan(boundaryMaxScan int) *Highlight {
 | |
| 	hl.boundaryMaxScan = &boundaryMaxScan
 | |
| 	return hl
 | |
| }
 | |
| 
 | |
| func (hl *Highlight) BoundaryChars(boundaryChars string) *Highlight {
 | |
| 	hl.boundaryChars = &boundaryChars
 | |
| 	return hl
 | |
| }
 | |
| 
 | |
| func (hl *Highlight) BoundaryScannerType(boundaryScannerType string) *Highlight {
 | |
| 	hl.boundaryScannerType = &boundaryScannerType
 | |
| 	return hl
 | |
| }
 | |
| 
 | |
| func (hl *Highlight) BoundaryScannerLocale(boundaryScannerLocale string) *Highlight {
 | |
| 	hl.boundaryScannerLocale = &boundaryScannerLocale
 | |
| 	return hl
 | |
| }
 | |
| 
 | |
| func (hl *Highlight) HighlighterType(highlighterType string) *Highlight {
 | |
| 	hl.highlighterType = &highlighterType
 | |
| 	return hl
 | |
| }
 | |
| 
 | |
| func (hl *Highlight) Fragmenter(fragmenter string) *Highlight {
 | |
| 	hl.fragmenter = &fragmenter
 | |
| 	return hl
 | |
| }
 | |
| 
 | |
| func (hl *Highlight) HighlightQuery(highlightQuery Query) *Highlight {
 | |
| 	hl.highlightQuery = highlightQuery
 | |
| 	return hl
 | |
| }
 | |
| 
 | |
| func (hl *Highlight) NoMatchSize(noMatchSize int) *Highlight {
 | |
| 	hl.noMatchSize = &noMatchSize
 | |
| 	return hl
 | |
| }
 | |
| 
 | |
| func (hl *Highlight) Options(options map[string]interface{}) *Highlight {
 | |
| 	hl.options = options
 | |
| 	return hl
 | |
| }
 | |
| 
 | |
| func (hl *Highlight) ForceSource(forceSource bool) *Highlight {
 | |
| 	hl.forceSource = &forceSource
 | |
| 	return hl
 | |
| }
 | |
| 
 | |
| func (hl *Highlight) UseExplicitFieldOrder(useExplicitFieldOrder bool) *Highlight {
 | |
| 	hl.useExplicitFieldOrder = useExplicitFieldOrder
 | |
| 	return hl
 | |
| }
 | |
| 
 | |
| // Creates the query source for the bool query.
 | |
| func (hl *Highlight) Source() (interface{}, error) {
 | |
| 	// Returns the map inside of "highlight":
 | |
| 	// "highlight":{
 | |
| 	//   ... this ...
 | |
| 	// }
 | |
| 	source := make(map[string]interface{})
 | |
| 	if hl.tagsSchema != nil {
 | |
| 		source["tags_schema"] = *hl.tagsSchema
 | |
| 	}
 | |
| 	if hl.preTags != nil && len(hl.preTags) > 0 {
 | |
| 		source["pre_tags"] = hl.preTags
 | |
| 	}
 | |
| 	if hl.postTags != nil && len(hl.postTags) > 0 {
 | |
| 		source["post_tags"] = hl.postTags
 | |
| 	}
 | |
| 	if hl.order != nil {
 | |
| 		source["order"] = *hl.order
 | |
| 	}
 | |
| 	if hl.highlightFilter != nil {
 | |
| 		source["highlight_filter"] = *hl.highlightFilter
 | |
| 	}
 | |
| 	if hl.fragmentSize != nil {
 | |
| 		source["fragment_size"] = *hl.fragmentSize
 | |
| 	}
 | |
| 	if hl.numOfFragments != nil {
 | |
| 		source["number_of_fragments"] = *hl.numOfFragments
 | |
| 	}
 | |
| 	if hl.encoder != nil {
 | |
| 		source["encoder"] = *hl.encoder
 | |
| 	}
 | |
| 	if hl.requireFieldMatch != nil {
 | |
| 		source["require_field_match"] = *hl.requireFieldMatch
 | |
| 	}
 | |
| 	if hl.boundaryMaxScan != nil {
 | |
| 		source["boundary_max_scan"] = *hl.boundaryMaxScan
 | |
| 	}
 | |
| 	if hl.boundaryChars != nil {
 | |
| 		source["boundary_chars"] = *hl.boundaryChars
 | |
| 	}
 | |
| 	if hl.boundaryScannerType != nil {
 | |
| 		source["boundary_scanner"] = *hl.boundaryScannerType
 | |
| 	}
 | |
| 	if hl.boundaryScannerLocale != nil {
 | |
| 		source["boundary_scanner_locale"] = *hl.boundaryScannerLocale
 | |
| 	}
 | |
| 	if hl.highlighterType != nil {
 | |
| 		source["type"] = *hl.highlighterType
 | |
| 	}
 | |
| 	if hl.fragmenter != nil {
 | |
| 		source["fragmenter"] = *hl.fragmenter
 | |
| 	}
 | |
| 	if hl.highlightQuery != nil {
 | |
| 		src, err := hl.highlightQuery.Source()
 | |
| 		if err != nil {
 | |
| 			return nil, err
 | |
| 		}
 | |
| 		source["highlight_query"] = src
 | |
| 	}
 | |
| 	if hl.noMatchSize != nil {
 | |
| 		source["no_match_size"] = *hl.noMatchSize
 | |
| 	}
 | |
| 	if hl.phraseLimit != nil {
 | |
| 		source["phrase_limit"] = *hl.phraseLimit
 | |
| 	}
 | |
| 	if hl.options != nil && len(hl.options) > 0 {
 | |
| 		source["options"] = hl.options
 | |
| 	}
 | |
| 	if hl.forceSource != nil {
 | |
| 		source["force_source"] = *hl.forceSource
 | |
| 	}
 | |
| 
 | |
| 	if hl.fields != nil && len(hl.fields) > 0 {
 | |
| 		if hl.useExplicitFieldOrder {
 | |
| 			// Use a slice for the fields
 | |
| 			var fields []map[string]interface{}
 | |
| 			for _, field := range hl.fields {
 | |
| 				src, err := field.Source()
 | |
| 				if err != nil {
 | |
| 					return nil, err
 | |
| 				}
 | |
| 				fmap := make(map[string]interface{})
 | |
| 				fmap[field.Name] = src
 | |
| 				fields = append(fields, fmap)
 | |
| 			}
 | |
| 			source["fields"] = fields
 | |
| 		} else {
 | |
| 			// Use a map for the fields
 | |
| 			fields := make(map[string]interface{})
 | |
| 			for _, field := range hl.fields {
 | |
| 				src, err := field.Source()
 | |
| 				if err != nil {
 | |
| 					return nil, err
 | |
| 				}
 | |
| 				fields[field.Name] = src
 | |
| 			}
 | |
| 			source["fields"] = fields
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	return source, nil
 | |
| }
 | |
| 
 | |
| // HighlighterField specifies a highlighted field.
 | |
| type HighlighterField struct {
 | |
| 	Name string
 | |
| 
 | |
| 	preTags           []string
 | |
| 	postTags          []string
 | |
| 	fragmentSize      int
 | |
| 	fragmentOffset    int
 | |
| 	numOfFragments    int
 | |
| 	highlightFilter   *bool
 | |
| 	order             *string
 | |
| 	requireFieldMatch *bool
 | |
| 	boundaryMaxScan   int
 | |
| 	boundaryChars     []rune
 | |
| 	highlighterType   *string
 | |
| 	fragmenter        *string
 | |
| 	highlightQuery    Query
 | |
| 	noMatchSize       *int
 | |
| 	matchedFields     []string
 | |
| 	phraseLimit       *int
 | |
| 	options           map[string]interface{}
 | |
| 	forceSource       *bool
 | |
| 
 | |
| 	/*
 | |
| 		Name              string
 | |
| 		preTags           []string
 | |
| 		postTags          []string
 | |
| 		fragmentSize      int
 | |
| 		numOfFragments    int
 | |
| 		fragmentOffset    int
 | |
| 		highlightFilter   *bool
 | |
| 		order             string
 | |
| 		requireFieldMatch *bool
 | |
| 		boundaryMaxScan   int
 | |
| 		boundaryChars     []rune
 | |
| 		highlighterType   string
 | |
| 		fragmenter        string
 | |
| 		highlightQuery    Query
 | |
| 		noMatchSize       *int
 | |
| 		matchedFields     []string
 | |
| 		options           map[string]interface{}
 | |
| 		forceSource       *bool
 | |
| 	*/
 | |
| }
 | |
| 
 | |
| func NewHighlighterField(name string) *HighlighterField {
 | |
| 	return &HighlighterField{
 | |
| 		Name:            name,
 | |
| 		preTags:         make([]string, 0),
 | |
| 		postTags:        make([]string, 0),
 | |
| 		fragmentSize:    -1,
 | |
| 		fragmentOffset:  -1,
 | |
| 		numOfFragments:  -1,
 | |
| 		boundaryMaxScan: -1,
 | |
| 		boundaryChars:   make([]rune, 0),
 | |
| 		matchedFields:   make([]string, 0),
 | |
| 		options:         make(map[string]interface{}),
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func (f *HighlighterField) PreTags(preTags ...string) *HighlighterField {
 | |
| 	f.preTags = append(f.preTags, preTags...)
 | |
| 	return f
 | |
| }
 | |
| 
 | |
| func (f *HighlighterField) PostTags(postTags ...string) *HighlighterField {
 | |
| 	f.postTags = append(f.postTags, postTags...)
 | |
| 	return f
 | |
| }
 | |
| 
 | |
| func (f *HighlighterField) FragmentSize(fragmentSize int) *HighlighterField {
 | |
| 	f.fragmentSize = fragmentSize
 | |
| 	return f
 | |
| }
 | |
| 
 | |
| func (f *HighlighterField) FragmentOffset(fragmentOffset int) *HighlighterField {
 | |
| 	f.fragmentOffset = fragmentOffset
 | |
| 	return f
 | |
| }
 | |
| 
 | |
| func (f *HighlighterField) NumOfFragments(numOfFragments int) *HighlighterField {
 | |
| 	f.numOfFragments = numOfFragments
 | |
| 	return f
 | |
| }
 | |
| 
 | |
| func (f *HighlighterField) HighlightFilter(highlightFilter bool) *HighlighterField {
 | |
| 	f.highlightFilter = &highlightFilter
 | |
| 	return f
 | |
| }
 | |
| 
 | |
| func (f *HighlighterField) Order(order string) *HighlighterField {
 | |
| 	f.order = &order
 | |
| 	return f
 | |
| }
 | |
| 
 | |
| func (f *HighlighterField) RequireFieldMatch(requireFieldMatch bool) *HighlighterField {
 | |
| 	f.requireFieldMatch = &requireFieldMatch
 | |
| 	return f
 | |
| }
 | |
| 
 | |
| func (f *HighlighterField) BoundaryMaxScan(boundaryMaxScan int) *HighlighterField {
 | |
| 	f.boundaryMaxScan = boundaryMaxScan
 | |
| 	return f
 | |
| }
 | |
| 
 | |
| func (f *HighlighterField) BoundaryChars(boundaryChars ...rune) *HighlighterField {
 | |
| 	f.boundaryChars = append(f.boundaryChars, boundaryChars...)
 | |
| 	return f
 | |
| }
 | |
| 
 | |
| func (f *HighlighterField) HighlighterType(highlighterType string) *HighlighterField {
 | |
| 	f.highlighterType = &highlighterType
 | |
| 	return f
 | |
| }
 | |
| 
 | |
| func (f *HighlighterField) Fragmenter(fragmenter string) *HighlighterField {
 | |
| 	f.fragmenter = &fragmenter
 | |
| 	return f
 | |
| }
 | |
| 
 | |
| func (f *HighlighterField) HighlightQuery(highlightQuery Query) *HighlighterField {
 | |
| 	f.highlightQuery = highlightQuery
 | |
| 	return f
 | |
| }
 | |
| 
 | |
| func (f *HighlighterField) NoMatchSize(noMatchSize int) *HighlighterField {
 | |
| 	f.noMatchSize = &noMatchSize
 | |
| 	return f
 | |
| }
 | |
| 
 | |
| func (f *HighlighterField) Options(options map[string]interface{}) *HighlighterField {
 | |
| 	f.options = options
 | |
| 	return f
 | |
| }
 | |
| 
 | |
| func (f *HighlighterField) MatchedFields(matchedFields ...string) *HighlighterField {
 | |
| 	f.matchedFields = append(f.matchedFields, matchedFields...)
 | |
| 	return f
 | |
| }
 | |
| 
 | |
| func (f *HighlighterField) PhraseLimit(phraseLimit int) *HighlighterField {
 | |
| 	f.phraseLimit = &phraseLimit
 | |
| 	return f
 | |
| }
 | |
| 
 | |
| func (f *HighlighterField) ForceSource(forceSource bool) *HighlighterField {
 | |
| 	f.forceSource = &forceSource
 | |
| 	return f
 | |
| }
 | |
| 
 | |
| func (f *HighlighterField) Source() (interface{}, error) {
 | |
| 	source := make(map[string]interface{})
 | |
| 
 | |
| 	if f.preTags != nil && len(f.preTags) > 0 {
 | |
| 		source["pre_tags"] = f.preTags
 | |
| 	}
 | |
| 	if f.postTags != nil && len(f.postTags) > 0 {
 | |
| 		source["post_tags"] = f.postTags
 | |
| 	}
 | |
| 	if f.fragmentSize != -1 {
 | |
| 		source["fragment_size"] = f.fragmentSize
 | |
| 	}
 | |
| 	if f.numOfFragments != -1 {
 | |
| 		source["number_of_fragments"] = f.numOfFragments
 | |
| 	}
 | |
| 	if f.fragmentOffset != -1 {
 | |
| 		source["fragment_offset"] = f.fragmentOffset
 | |
| 	}
 | |
| 	if f.highlightFilter != nil {
 | |
| 		source["highlight_filter"] = *f.highlightFilter
 | |
| 	}
 | |
| 	if f.order != nil {
 | |
| 		source["order"] = *f.order
 | |
| 	}
 | |
| 	if f.requireFieldMatch != nil {
 | |
| 		source["require_field_match"] = *f.requireFieldMatch
 | |
| 	}
 | |
| 	if f.boundaryMaxScan != -1 {
 | |
| 		source["boundary_max_scan"] = f.boundaryMaxScan
 | |
| 	}
 | |
| 	if f.boundaryChars != nil && len(f.boundaryChars) > 0 {
 | |
| 		source["boundary_chars"] = f.boundaryChars
 | |
| 	}
 | |
| 	if f.highlighterType != nil {
 | |
| 		source["type"] = *f.highlighterType
 | |
| 	}
 | |
| 	if f.fragmenter != nil {
 | |
| 		source["fragmenter"] = *f.fragmenter
 | |
| 	}
 | |
| 	if f.highlightQuery != nil {
 | |
| 		src, err := f.highlightQuery.Source()
 | |
| 		if err != nil {
 | |
| 			return nil, err
 | |
| 		}
 | |
| 		source["highlight_query"] = src
 | |
| 	}
 | |
| 	if f.noMatchSize != nil {
 | |
| 		source["no_match_size"] = *f.noMatchSize
 | |
| 	}
 | |
| 	if f.matchedFields != nil && len(f.matchedFields) > 0 {
 | |
| 		source["matched_fields"] = f.matchedFields
 | |
| 	}
 | |
| 	if f.phraseLimit != nil {
 | |
| 		source["phrase_limit"] = *f.phraseLimit
 | |
| 	}
 | |
| 	if f.options != nil && len(f.options) > 0 {
 | |
| 		source["options"] = f.options
 | |
| 	}
 | |
| 	if f.forceSource != nil {
 | |
| 		source["force_source"] = *f.forceSource
 | |
| 	}
 | |
| 
 | |
| 	return source, nil
 | |
| }
 |